From 8865b031c1ecf39ab4b658c9e5b923ca2f355c04 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Sep 2015 17:01:14 +0200 Subject: [PATCH 001/214] added bundle com.sap.sailing.competitorimport --- .../.classpath | 7 +++++ .../com.sap.sailing.competitorimport/.project | 28 +++++++++++++++++++ .../.settings/org.eclipse.jdt.core.prefs | 7 +++++ .../.settings/org.eclipse.pde.core.prefs | 3 ++ .../META-INF/MANIFEST.MF | 7 +++++ .../build.properties | 4 +++ .../competitorimport/CompetitorProvider.java | 20 +++++++++++++ 7 files changed, 76 insertions(+) create mode 100644 java/com.sap.sailing.competitorimport/.classpath create mode 100644 java/com.sap.sailing.competitorimport/.project create mode 100644 java/com.sap.sailing.competitorimport/.settings/org.eclipse.jdt.core.prefs create mode 100644 java/com.sap.sailing.competitorimport/.settings/org.eclipse.pde.core.prefs create mode 100644 java/com.sap.sailing.competitorimport/META-INF/MANIFEST.MF create mode 100644 java/com.sap.sailing.competitorimport/build.properties create mode 100644 java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java diff --git a/java/com.sap.sailing.competitorimport/.classpath b/java/com.sap.sailing.competitorimport/.classpath new file mode 100644 index 00000000000..b862a296d38 --- /dev/null +++ b/java/com.sap.sailing.competitorimport/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/com.sap.sailing.competitorimport/.project b/java/com.sap.sailing.competitorimport/.project new file mode 100644 index 00000000000..c43491b2887 --- /dev/null +++ b/java/com.sap.sailing.competitorimport/.project @@ -0,0 +1,28 @@ + + + com.sap.sailing.competitorimport + + + + + + 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.competitorimport/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sailing.competitorimport/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..295926d9641 --- /dev/null +++ b/java/com.sap.sailing.competitorimport/.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.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/java/com.sap.sailing.competitorimport/.settings/org.eclipse.pde.core.prefs b/java/com.sap.sailing.competitorimport/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 00000000000..b7e72d019c2 --- /dev/null +++ b/java/com.sap.sailing.competitorimport/.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.competitorimport/META-INF/MANIFEST.MF b/java/com.sap.sailing.competitorimport/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..6a9a32014fe --- /dev/null +++ b/java/com.sap.sailing.competitorimport/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Competitorimport +Bundle-SymbolicName: com.sap.sailing.competitorimport +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: SAP +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/java/com.sap.sailing.competitorimport/build.properties b/java/com.sap.sailing.competitorimport/build.properties new file mode 100644 index 00000000000..41eb6ade2b4 --- /dev/null +++ b/java/com.sap.sailing.competitorimport/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java new file mode 100644 index 00000000000..dc12e71c046 --- /dev/null +++ b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java @@ -0,0 +1,20 @@ +package com.sap.sailing.competitorimport; + +/** + * Competitor data may come from various sources, such as external regatta management systems (RMS), + * CSV files, Excel spreadsheets and the like. When creating a regatta that uses "RaceLog Tracking" + * (also known as Smartphone Tracking)---and be it only in order to manage results for the regatta + * with the race committee app---it is tedious having to enter all competitor data manually when + * that data is already available in electronic form.

+ * + * In its simplest form, a provider will just produce an otherwise unstructured list of competitor + * entries with no hint as to the event, regatta or race that the competitor pertains to. More + * sophisticated providers may structure competitor data into events, regattas or even individual + * races so that + * + * @author Axel Uhl (d043530) + * + */ +public class CompetitorProvider { + +} From d3720fe707e8827ed16476cf5f809bddcbf73641 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 12:07:48 +0200 Subject: [PATCH 002/214] deliver the competitor of a RaceLogRegisterCompetitorEventImpl as the list of involved boats; this should also fix the serialization which always delivered an empty competitor list --- .../race/tracking/impl/RaceLogRegisterCompetitorEventImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/impl/RaceLogRegisterCompetitorEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/impl/RaceLogRegisterCompetitorEventImpl.java index fb3791e2963..eb20dd7f79a 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/impl/RaceLogRegisterCompetitorEventImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/impl/RaceLogRegisterCompetitorEventImpl.java @@ -1,6 +1,7 @@ package com.sap.sailing.domain.abstractlog.race.tracking.impl; import java.io.Serializable; +import java.util.Collections; import java.util.List; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; @@ -35,7 +36,7 @@ public class RaceLogRegisterCompetitorEventImpl extends BaseRegisterCompetitorEv @Override public List getInvolvedBoats() { - return raceLogEventData.getInvolvedBoats(); + return Collections.singletonList(getCompetitor()); } @Override From 6068191ce4f9e9f8e792f52352a8e554bb713aa6 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 12:08:30 +0200 Subject: [PATCH 003/214] started to implement a competitor import for Manage2Sail / XRR --- .../competitorimport/CompetitorProvider.java | 4 +- .../AbstractEventResultJsonServiceTest.java | 21 ++++ .../test/CompetitorImportTest.java | 30 ++++++ .../test/EventResultJsonServiceTest.java | 20 +--- .../resultimport/test/ParserTest.java | 1 - .../META-INF/MANIFEST.MF | 6 +- .../AbstractManage2SailProvider.java | 38 +++++++ ...ractManage2SailResultDocumentProvider.java | 61 ++++++++++++ .../resultimport/CompetitorDescriptor.java | 98 +++++++++++++++++++ .../CompetitorDocumentProvider.java | 17 ++++ .../resultimport/CompetitorImporter.java | 94 ++++++++++++++++++ .../Manage2SailResultDocumentProvider.java | 55 +++-------- .../ScoreCorrectionProviderImpl.java | 65 +++++------- .../sap/sailing/xrr/resultimport/Parser.java | 3 + .../xrr/resultimport/impl/ParserImpl.java | 18 ++++ 15 files changed, 424 insertions(+), 107 deletions(-) create mode 100644 java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/AbstractEventResultJsonServiceTest.java create mode 100644 java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java create mode 100644 java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailProvider.java create mode 100644 java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java create mode 100644 java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDescriptor.java create mode 100644 java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java create mode 100644 java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java diff --git a/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java index dc12e71c046..c38dbb5ebc6 100644 --- a/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java +++ b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java @@ -10,11 +10,11 @@ package com.sap.sailing.competitorimport; * In its simplest form, a provider will just produce an otherwise unstructured list of competitor * entries with no hint as to the event, regatta or race that the competitor pertains to. More * sophisticated providers may structure competitor data into events, regattas or even individual - * races so that + * races so that importing these competitors into a single fleet of one race column becomes possible. + * This will be particularly useful for split-fleet racing. * * @author Axel Uhl (d043530) * */ public class CompetitorProvider { - } diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/AbstractEventResultJsonServiceTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/AbstractEventResultJsonServiceTest.java new file mode 100644 index 00000000000..b2b0d76d5cd --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/AbstractEventResultJsonServiceTest.java @@ -0,0 +1,21 @@ +package com.sap.sailing.manage2sail.resultimport.test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +public class AbstractEventResultJsonServiceTest { + protected static final String EVENT_RESULTS_JSON = "eventResults.json"; + + protected static final String RESOURCES = "resources/"; + + protected InputStream getInputStream(String filename) throws FileNotFoundException, IOException { + return new FileInputStream(getFile(filename)); + } + + private File getFile(String filename) { + return new File(RESOURCES + filename); + } +} diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java new file mode 100644 index 00000000000..782309c52ee --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java @@ -0,0 +1,30 @@ +package com.sap.sailing.manage2sail.resultimport.test; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Arrays; + +import javax.xml.bind.JAXBException; + +import org.junit.Test; + +import com.sap.sailing.manage2sail.resultimport.AbstractManage2SailProvider; +import com.sap.sailing.manage2sail.resultimport.CompetitorDescriptor; +import com.sap.sailing.manage2sail.resultimport.CompetitorImporter; +import com.sap.sailing.resultimport.ResultUrlRegistry; +import com.sap.sailing.xrr.resultimport.ParserFactory; + +public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { + @Test + public void simpleCompetitorImportTest() throws FileNotFoundException, IOException, JAXBException { + ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); + when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource(EVENT_RESULTS_JSON))); + final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); + final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors(); + assertNotNull(competitorDescriptors); + } +} diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/EventResultJsonServiceTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/EventResultJsonServiceTest.java index 0f022000444..dcad5c4e8d9 100644 --- a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/EventResultJsonServiceTest.java +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/EventResultJsonServiceTest.java @@ -3,37 +3,19 @@ package com.sap.sailing.manage2sail.resultimport.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; import org.junit.Test; import com.sap.sailing.manage2sail.EventResultDescriptor; import com.sap.sailing.manage2sail.Manage2SailEventResultsParserImpl; -public class EventResultJsonServiceTest { - private static final String EVENT_RESULTS_JSON = "eventResults.json"; - - private static final String RESOURCES = "resources/"; - +public class EventResultJsonServiceTest extends AbstractEventResultJsonServiceTest { @Test public void testParsingEventResultsFromJson() throws IOException { Manage2SailEventResultsParserImpl parser = new Manage2SailEventResultsParserImpl(); - EventResultDescriptor eventResult = parser.getEventResult(getInputStream(EVENT_RESULTS_JSON)); assertNotNull(eventResult); - assertEquals(14, eventResult.getRegattaResults().size()); } - - private InputStream getInputStream(String filename) throws FileNotFoundException, IOException { - return new FileInputStream(getFile(filename)); - } - - private File getFile(String filename) { - return new File(RESOURCES + filename); - } } diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/ParserTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/ParserTest.java index c9587971f1f..5d4326808e3 100755 --- a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/ParserTest.java +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/ParserTest.java @@ -134,5 +134,4 @@ public class ParserTest { assertNotNull(scoreCorrectionsForRaces); assertEquals(8, Util.size(scoreCorrectionsForRaces)); } - } diff --git a/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF b/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF index af7d1626b9c..ff926200482 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF @@ -6,7 +6,8 @@ Bundle-Version: 1.0.0.qualifier Bundle-Activator: com.sap.sailing.manage2sail.resultimport.Activator Bundle-Vendor: SAP Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.osgi.framework;version="1.5.0", +Import-Package: java_cup, + org.osgi.framework;version="1.5.0", org.osgi.util.tracker;version="1.5.1" Bundle-ActivationPolicy: lazy Require-Bundle: com.sap.sailing.manage2sail, @@ -14,4 +15,5 @@ Require-Bundle: com.sap.sailing.manage2sail, com.sap.sailing.resultimport, com.sap.sailing.xrr.resultimport, com.sap.sse.common, - com.sap.sailing.xrr.schema + com.sap.sailing.xrr.schema, + com.sap.sailing.domain.shared.android diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailProvider.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailProvider.java new file mode 100644 index 00000000000..7d1d7fa74e3 --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailProvider.java @@ -0,0 +1,38 @@ +package com.sap.sailing.manage2sail.resultimport; + +import java.net.URL; + +import com.sap.sailing.resultimport.ResultUrlProvider; +import com.sap.sailing.resultimport.ResultUrlRegistry; +import com.sap.sailing.xrr.resultimport.ParserFactory; + +public abstract class AbstractManage2SailProvider implements ResultUrlProvider { + public static final String NAME = "Manage2Sail XRR Result Importer"; + + private final ParserFactory parserFactory; + private final ResultUrlRegistry resultUrlRegistry; + + protected AbstractManage2SailProvider(ParserFactory parserFactory, ResultUrlRegistry resultUrlRegistry) { + super(); + this.parserFactory = parserFactory; + this.resultUrlRegistry = resultUrlRegistry; + } + + protected ParserFactory getParserFactory() { + return parserFactory; + } + + protected ResultUrlRegistry getResultUrlRegistry() { + return resultUrlRegistry; + } + + @Override + public Iterable getUrls() { + return getResultUrlRegistry().getResultUrls(NAME); + } + + @Override + public String getOptionalSampleURL() { + return "http://manage2sail.com/api/public/links/event/d30883d3-2876-4d7e-af49-891af6cbae1b?accesstoken=bDAv8CwsTM94ujZ&mediaType=json"; + } +} diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java new file mode 100644 index 00000000000..16653098c4c --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java @@ -0,0 +1,61 @@ +package com.sap.sailing.manage2sail.resultimport; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + +import com.sap.sailing.manage2sail.EventResultDescriptor; +import com.sap.sailing.manage2sail.Manage2SailEventResultsParserImpl; +import com.sap.sailing.manage2sail.RegattaResultDescriptor; +import com.sap.sailing.resultimport.ResultDocumentDescriptor; +import com.sap.sailing.resultimport.ResultUrlProvider; +import com.sap.sailing.resultimport.impl.ResultDocumentDescriptorImpl; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +public abstract class AbstractManage2SailResultDocumentProvider { + private final ResultUrlProvider resultUrlProvider; + + public AbstractManage2SailResultDocumentProvider(final ResultUrlProvider resultUrlProvider) { + this.resultUrlProvider = resultUrlProvider; + } + + public Iterable getResultDocumentDescriptors() throws IOException { + List result = new ArrayList<>(); + Manage2SailEventResultsParserImpl parser = new Manage2SailEventResultsParserImpl(); + for (URL url : resultUrlProvider.getUrls()) { + URLConnection eventResultConn = url.openConnection(); + EventResultDescriptor eventResult = parser.getEventResult((InputStream) eventResultConn.getContent()); + addResultsForEvent(result, eventResult); + } + return result; + } + + private void addResultsForEvent(List result, EventResultDescriptor eventResult) + throws IOException { + if (eventResult != null) { + for (RegattaResultDescriptor regattaResult : eventResult.getRegattaResults()) { + // Depending on the regatta type the boat class in the XRR is set or not (in the division tag) + // Olympic boat classes -> IFClassID="2.4M" Title="2.4M open" + // International boat classes -> IFClassID="" Title="Coachboat" + // Open boat classes (ORC) -> IFClassID="" Title="Welcome Race ORC-Club" + // -> therefore we need to take the regatta title as boat class where the IsafID is not available + String boatClass = regattaResult.getIsafId() != null && !regattaResult.getIsafId().isEmpty() ? regattaResult.getIsafId() : regattaResult.getName(); + if (regattaResult.getIsFinal() != null && regattaResult.getPublishedAt() != null) { + final URL resultUrl = getDocumentUrlForRegatta(regattaResult); + if (resultUrl != null) { + URLConnection regattaResultConn = resultUrl.openConnection(); + result.add(new ResultDocumentDescriptorImpl((InputStream) regattaResultConn.getContent(), + resultUrl.toString(), new MillisecondsTimePoint(regattaResult.getPublishedAt()), + eventResult.getName(), regattaResult.getName(), boatClass, regattaResult + .getCompetitorGenderType())); + } + } + } + } + } + + abstract protected URL getDocumentUrlForRegatta(RegattaResultDescriptor regattaResult); +} diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDescriptor.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDescriptor.java new file mode 100644 index 00000000000..561e59193c6 --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDescriptor.java @@ -0,0 +1,98 @@ +package com.sap.sailing.manage2sail.resultimport; + +import com.sap.sailing.domain.base.Person; +import com.sap.sse.common.CountryCode; + +public class CompetitorDescriptor { + private String eventName; + private String regattaName; + private String raceName; + private String fleetName; + private String sailNumber; + private String competitorName; + private CountryCode countryCode; + private Iterable persons; + + public CompetitorDescriptor(String eventName, String regattaName, String raceName, String fleetName, + String sailNumber, String competitorName, CountryCode countryCode, Iterable persons) { + super(); + this.eventName = eventName; + this.regattaName = regattaName; + this.raceName = raceName; + this.fleetName = fleetName; + this.sailNumber = sailNumber; + this.competitorName = competitorName; + this.countryCode = countryCode; + this.persons = persons; + } + + public String getEventName() { + return eventName; + } + + public void setEventName(String eventName) { + this.eventName = eventName; + } + + public String getRegattaName() { + return regattaName; + } + + public void setRegattaName(String regattaName) { + this.regattaName = regattaName; + } + + public String getRaceName() { + return raceName; + } + + public void setRaceName(String raceName) { + this.raceName = raceName; + } + + public String getFleetName() { + return fleetName; + } + + public void setFleetName(String fleetName) { + this.fleetName = fleetName; + } + + public String getSailNumber() { + return sailNumber; + } + + public void setSailNumber(String sailNumber) { + this.sailNumber = sailNumber; + } + + public String getCompetitorName() { + return competitorName; + } + + public void setCompetitorName(String competitorName) { + this.competitorName = competitorName; + } + + public CountryCode getCountryCode() { + return countryCode; + } + + public void setCountryCode(CountryCode threeLetterIOCCountryCode) { + this.countryCode = threeLetterIOCCountryCode; + } + + public Iterable getPersons() { + return persons; + } + + public void setPersons(Iterable persons) { + this.persons = persons; + } + + @Override + public String toString() { + return ""+countryCode+" "+sailNumber+" "+getCompetitorName()+" at event: "+eventName+", regatta: "+regattaName+", race: "+raceName+ + ", fleet: "+fleetName+", "+persons; + } +} diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java new file mode 100644 index 00000000000..bd6eb782ab1 --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java @@ -0,0 +1,17 @@ +package com.sap.sailing.manage2sail.resultimport; + +import java.net.URL; + +import com.sap.sailing.manage2sail.RegattaResultDescriptor; +import com.sap.sailing.resultimport.ResultUrlProvider; + +public class CompetitorDocumentProvider extends AbstractManage2SailResultDocumentProvider { + public CompetitorDocumentProvider(ResultUrlProvider resultUrlProvider) { + super(resultUrlProvider); + } + + @Override + protected URL getDocumentUrlForRegatta(RegattaResultDescriptor regattaResult) { + return regattaResult.getXrrEntriesUrl(); + } +} diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java new file mode 100644 index 00000000000..b30587e63b1 --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java @@ -0,0 +1,94 @@ +package com.sap.sailing.manage2sail.resultimport; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.xml.bind.JAXBException; + +import com.sap.sailing.domain.base.Nationality; +import com.sap.sailing.domain.base.impl.NationalityImpl; +import com.sap.sailing.domain.base.impl.PersonImpl; +import com.sap.sailing.resultimport.ResultDocumentDescriptor; +import com.sap.sailing.resultimport.ResultUrlRegistry; +import com.sap.sailing.xrr.resultimport.Parser; +import com.sap.sailing.xrr.resultimport.ParserFactory; +import com.sap.sailing.xrr.schema.Boat; +import com.sap.sailing.xrr.schema.Division; +import com.sap.sailing.xrr.schema.Event; +import com.sap.sailing.xrr.schema.Person; +import com.sap.sailing.xrr.schema.Race; +import com.sap.sailing.xrr.schema.RaceResult; +import com.sap.sailing.xrr.schema.RegattaResults; +import com.sap.sailing.xrr.schema.SeriesResult; +import com.sap.sailing.xrr.schema.Team; + +public class CompetitorImporter extends AbstractManage2SailProvider { + private final CompetitorDocumentProvider documentProvider; + + public CompetitorImporter(ParserFactory parserFactory, ResultUrlRegistry resultUrlRegistry) { + super(parserFactory, resultUrlRegistry); + documentProvider = new CompetitorDocumentProvider(this); + } + + public Iterable getCompetitorDescriptors() throws JAXBException, IOException { + final List result = new ArrayList<>(); + for (ResultDocumentDescriptor resultDocDescr : documentProvider.getResultDocumentDescriptors()) { + final Parser parser = getParserFactory().createParser(resultDocDescr.getInputStream(), resultDocDescr.getEventName()); + final RegattaResults regattaResults = parser.parse(); + for (Object o : regattaResults.getPersonOrBoatOrTeam()) { + if (o instanceof Event) { + Event event = (Event) o; + for (Object eventO : event.getRaceOrDivisionOrRegattaSeriesResult()) { + if (eventO instanceof Division) { + Division division = (Division) eventO; + for (Object divisionO : division.getSeriesResultOrRaceResultOrTRResult()) { + String raceID = null; + Team team = null; + if (divisionO instanceof RaceResult) { + RaceResult raceResult = (RaceResult) divisionO; + raceID = raceResult.getRaceID(); + team = parser.getTeam(raceResult.getTeamID()); + } else if (divisionO instanceof SeriesResult) { + SeriesResult seriesResult = (SeriesResult) divisionO; + team = parser.getTeam(seriesResult.getTeamID()); + } + if (team != null) { + final Boat boat = parser.getBoat(team.getBoatID()); + final String sailNumber = boat.getSailNumber(); + final Race race = parser.getRace(raceID); + final Nationality[] teamNationality = new Nationality[] { + // use that of team; if not defined for team, use first nationality of a team member that has one defined + team.getNOC() == null ? null : new NationalityImpl(team.getNOC().name()) + }; + List persons = team.getCrew().stream().sorted((c1, c2) -> -c1.getPosition().name().compareTo(c2.getPosition().name())).map((crew)->{ + Person xrrPerson = parser.getPerson(crew.getPersonID()); + String name = xrrPerson.getGivenName()+" "+xrrPerson.getFamilyName(); + final Nationality nationality; + if (xrrPerson.getNOC() == null) { + nationality = null; + } else { + nationality = new NationalityImpl(xrrPerson.getNOC().name()); + if (teamNationality[0] == null) { + teamNationality[0] = nationality; + } + } + com.sap.sailing.domain.base.Person person = new PersonImpl(name, nationality, /* date of birth */ null, /* description */ xrrPerson.getGender().name()); + return person; + }).collect(Collectors.toList()); + final CompetitorDescriptor competitorDescriptor = new CompetitorDescriptor( + event.getTitle(), division.getTitle() + (division.getGender() == null ? "" : division.getGender().name()), + race != null ? race.getRaceName() : null, /* fleetName */ null, sailNumber, team.getTeamName(), + teamNationality[0] == null ? null : teamNationality[0].getCountryCode(), persons); + result.add(competitorDescriptor); + } + } + } + } + } + } + } + return result; + } +} diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java index f3a71db39eb..a2cf59735d4 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java @@ -1,59 +1,34 @@ package com.sap.sailing.manage2sail.resultimport; import java.io.IOException; -import java.io.InputStream; import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.List; -import com.sap.sailing.manage2sail.EventResultDescriptor; -import com.sap.sailing.manage2sail.Manage2SailEventResultsParserImpl; import com.sap.sailing.manage2sail.RegattaResultDescriptor; import com.sap.sailing.resultimport.ResultDocumentDescriptor; import com.sap.sailing.resultimport.ResultDocumentProvider; import com.sap.sailing.resultimport.ResultUrlProvider; -import com.sap.sailing.resultimport.impl.ResultDocumentDescriptorImpl; -import com.sap.sse.common.impl.MillisecondsTimePoint; -public class Manage2SailResultDocumentProvider implements ResultDocumentProvider { - private final ResultUrlProvider resultUrlProvider; +public class Manage2SailResultDocumentProvider extends AbstractManage2SailResultDocumentProvider implements ResultDocumentProvider { public Manage2SailResultDocumentProvider(final ResultUrlProvider resultUrlProvider) { - this.resultUrlProvider = resultUrlProvider; + super(resultUrlProvider); } @Override public Iterable getResultDocumentDescriptors() throws IOException { - List result = new ArrayList<>(); - Manage2SailEventResultsParserImpl parser = new Manage2SailEventResultsParserImpl(); - for (URL url : resultUrlProvider.getUrls()) { - URLConnection eventResultConn = url.openConnection(); - EventResultDescriptor eventResult = parser.getEventResult((InputStream) eventResultConn.getContent()); - if (eventResult != null) { - for (RegattaResultDescriptor regattaResult : eventResult.getRegattaResults()) { - // Depending on the regatta type the boat class in the XRR is set or not (in the division tag) - // Olympic boat classes -> IFClassID="2.4M" Title="2.4M open" - // International boat classes -> IFClassID="" Title="Coachboat" - // Open boat classes (ORC) -> IFClassID="" Title="Welcome Race ORC-Club" - // -> therefore we need to take the regatta title as boat class where the IsafID is not available - String boatClass = regattaResult.getIsafId() != null && !regattaResult.getIsafId().isEmpty() ? regattaResult.getIsafId() : regattaResult.getName(); - if (regattaResult.getIsFinal() != null && regattaResult.getPublishedAt() != null) { - if (regattaResult.getIsFinal() && regattaResult.getXrrFinalUrl() != null) { - URLConnection regattaResultConn = regattaResult.getXrrFinalUrl().openConnection(); - result.add(new ResultDocumentDescriptorImpl((InputStream) regattaResultConn.getContent(), - regattaResult.getXrrPreliminaryUrl().toString(), new MillisecondsTimePoint(regattaResult.getPublishedAt()), - eventResult.getName(), regattaResult.getName(), boatClass, regattaResult.getCompetitorGenderType())); - } else if (regattaResult.getXrrPreliminaryUrl() != null) { - URLConnection regattaResultConn = regattaResult.getXrrPreliminaryUrl().openConnection(); - result.add(new ResultDocumentDescriptorImpl((InputStream) regattaResultConn.getContent(), - regattaResult.getXrrPreliminaryUrl().toString(), new MillisecondsTimePoint(regattaResult.getPublishedAt()), - eventResult.getName(), regattaResult.getName(), boatClass, regattaResult.getCompetitorGenderType())); - } - } - } - } + return super.getResultDocumentDescriptors(); + } + + @Override + protected URL getDocumentUrlForRegatta(RegattaResultDescriptor regattaResult) { + final URL resultUrl; + if (regattaResult.getIsFinal() && regattaResult.getXrrFinalUrl() != null) { + resultUrl = regattaResult.getXrrFinalUrl(); + } else if (regattaResult.getXrrPreliminaryUrl() != null) { + resultUrl = regattaResult.getXrrPreliminaryUrl(); + } else { + resultUrl = null; } - return result; + return resultUrl; } } diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/ScoreCorrectionProviderImpl.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/ScoreCorrectionProviderImpl.java index 7d779cc658d..49a12e74f0a 100755 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/ScoreCorrectionProviderImpl.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/ScoreCorrectionProviderImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.manage2sail.resultimport; import java.io.IOException; -import java.net.URL; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -17,7 +16,6 @@ import com.sap.sailing.domain.common.RegattaScoreCorrections; import com.sap.sailing.domain.common.ScoreCorrectionProvider; import com.sap.sailing.resultimport.ResultDocumentDescriptor; import com.sap.sailing.resultimport.ResultDocumentProvider; -import com.sap.sailing.resultimport.ResultUrlProvider; import com.sap.sailing.resultimport.ResultUrlRegistry; import com.sap.sailing.xrr.resultimport.Parser; import com.sap.sailing.xrr.resultimport.ParserFactory; @@ -29,26 +27,20 @@ import com.sap.sailing.xrr.schema.RegattaResults; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; -public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider, ResultUrlProvider { +public class ScoreCorrectionProviderImpl extends AbstractManage2SailProvider implements ScoreCorrectionProvider { private static final Logger logger = Logger.getLogger(ScoreCorrectionProviderImpl.class.getName()); private static final long serialVersionUID = 222663322974305822L; - public static final String NAME = "Manage2Sail XRR Result Importer"; - - private final ParserFactory parserFactory; - private final ResultUrlRegistry resultUrlRegistry; private final ResultDocumentProvider documentProvider; public ScoreCorrectionProviderImpl(ResultDocumentProvider documentProvider, ParserFactory parserFactory, ResultUrlRegistry resultUrlRegistry) { + super(parserFactory, resultUrlRegistry); this.documentProvider = documentProvider; - this.parserFactory = parserFactory; - this.resultUrlRegistry = resultUrlRegistry; } public ScoreCorrectionProviderImpl(ParserFactory parserFactory, ResultUrlRegistry resultUrlRegistry) { + super(parserFactory, resultUrlRegistry); this.documentProvider = new Manage2SailResultDocumentProvider(this); - this.parserFactory = parserFactory; - this.resultUrlRegistry = resultUrlRegistry; } @Override @@ -87,29 +79,26 @@ public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider, Res Parser parser = resolveParser(eventName, boatClassName); try { RegattaResults regattaResults = parser.parse(); -// TimePoint timePoint = XRRParserUtil.calculateTimePointForRegattaResults(regattaResults); -// if ((timePoint == null && timePointPublished == null) || (timePoint != null && timePoint.equals(timePointPublished))) { - for (Object o : regattaResults.getPersonOrBoatOrTeam()) { - if (o instanceof Event) { - Event event = (Event) o; - if (event.getTitle().equals(eventName)) { - for (Object eventO : event.getRaceOrDivisionOrRegattaSeriesResult()) { - if (eventO instanceof Division) { - Division division = (Division) eventO; - EventGender divisionGender = division.getGender(); - String divisionBoatClassAndGender = parser.getBoatClassName(division); - if(divisionGender != null) { - divisionBoatClassAndGender += ", " + divisionGender.name(); - } - if (boatClassName.equalsIgnoreCase(divisionBoatClassAndGender) || boatClassName.contains(divisionBoatClassAndGender)) { - return new XRRRegattaResultsAsScoreCorrections(event, division, this, - parser); - } + for (Object o : regattaResults.getPersonOrBoatOrTeam()) { + if (o instanceof Event) { + Event event = (Event) o; + if (event.getTitle().equals(eventName)) { + for (Object eventO : event.getRaceOrDivisionOrRegattaSeriesResult()) { + if (eventO instanceof Division) { + Division division = (Division) eventO; + EventGender divisionGender = division.getGender(); + String divisionBoatClassAndGender = parser.getBoatClassName(division); + if(divisionGender != null) { + divisionBoatClassAndGender += ", " + divisionGender.name(); + } + if (boatClassName.equalsIgnoreCase(divisionBoatClassAndGender) || boatClassName.contains(divisionBoatClassAndGender)) { + return new XRRRegattaResultsAsScoreCorrections(event, division, this, + parser); } } } } -// } + } } } catch (JAXBException e) { logger.info("Parse error during XRR import. Ignoring document " + parser.toString()); @@ -122,24 +111,14 @@ public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider, Res Parser result = null; for (ResultDocumentDescriptor resultDocDescr : documentProvider.getResultDocumentDescriptors()) { String boatClassAndGenderType = resultDocDescr.getBoatClass(); - if(resultDocDescr.getCompetitorGenderType() != null) { + if (resultDocDescr.getCompetitorGenderType() != null) { boatClassAndGenderType += ", " + resultDocDescr.getCompetitorGenderType().name(); } - if(eventName.equals(resultDocDescr.getEventName()) && boatClassName.equals(boatClassAndGenderType)) { - result = parserFactory.createParser(resultDocDescr.getInputStream(), resultDocDescr.getEventName()); + if (eventName.equals(resultDocDescr.getEventName()) && boatClassName.equals(boatClassAndGenderType)) { + result = getParserFactory().createParser(resultDocDescr.getInputStream(), resultDocDescr.getEventName()); break; } } return result; } - - @Override - public Iterable getUrls() { - return resultUrlRegistry.getResultUrls(NAME); - } - - @Override - public String getOptionalSampleURL() { - return "http://manage2sail.com/api/public/links/event/d30883d3-2876-4d7e-af49-891af6cbae1b?accesstoken=bDAv8CwsTM94ujZ&mediaType=json"; - } } diff --git a/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/Parser.java b/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/Parser.java index f76ef31cd91..142cb4a8369 100755 --- a/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/Parser.java +++ b/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/Parser.java @@ -5,6 +5,7 @@ import javax.xml.bind.JAXBException; import com.sap.sailing.xrr.schema.Boat; import com.sap.sailing.xrr.schema.Division; import com.sap.sailing.xrr.schema.Person; +import com.sap.sailing.xrr.schema.Race; import com.sap.sailing.xrr.schema.RegattaResults; import com.sap.sailing.xrr.schema.Team; @@ -18,4 +19,6 @@ public interface Parser { Team getTeam(String teamID); Person getPerson(String personID); + + Race getRace(String raceID); } diff --git a/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/impl/ParserImpl.java b/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/impl/ParserImpl.java index 643f7f3682a..a11e790ebcf 100755 --- a/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/impl/ParserImpl.java +++ b/java/com.sap.sailing.xrr.resultimport/src/com/sap/sailing/xrr/resultimport/impl/ParserImpl.java @@ -12,7 +12,9 @@ import javax.xml.bind.Unmarshaller; import com.sap.sailing.xrr.resultimport.Parser; import com.sap.sailing.xrr.schema.Boat; import com.sap.sailing.xrr.schema.Division; +import com.sap.sailing.xrr.schema.Event; import com.sap.sailing.xrr.schema.Person; +import com.sap.sailing.xrr.schema.Race; import com.sap.sailing.xrr.schema.RegattaResults; import com.sap.sailing.xrr.schema.TRResult; import com.sap.sailing.xrr.schema.Team; @@ -22,6 +24,7 @@ public class ParserImpl implements Parser { private final Map personByID; private final Map teamByID; private final Map boatByID; + private final Map raceByID; private final InputStream inputStream; private final String name; @@ -30,6 +33,7 @@ public class ParserImpl implements Parser { this.personByID = new HashMap<>(); this.teamByID = new HashMap<>(); this.boatByID = new HashMap<>(); + this.raceByID = new HashMap<>(); this.inputStream = inputStream; this.name = name; } @@ -50,6 +54,14 @@ public class ParserImpl implements Parser { } else if (o instanceof Team) { Team team = (Team) o; teamByID.put(team.getTeamID(), team); + } else if (o instanceof Event) { + Event event = (Event) o; + for (Object o2 : event.getRaceOrDivisionOrRegattaSeriesResult()) { + if (o2 instanceof Race) { + Race race = (Race) o2; + raceByID.put(race.getRaceID(), race); + } + } } } return regattaResults; @@ -79,8 +91,14 @@ public class ParserImpl implements Parser { return personByID.get(personID); } + @Override + public Race getRace(String raceID) { + return raceByID.get(raceID); + } + @Override public String toString() { return name==null?"":name; } + } From c0b9778127cd95a2367b4a06acc3b07e7362e08f Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 17:01:56 +0200 Subject: [PATCH 004/214] enhanced competitor import test case, testing regattaName parameter --- .../META-INF/MANIFEST.MF | 3 + java/com.sap.sailing.competitorimport/pom.xml | 12 ++ .../CompetitorDescriptor.java | 3 +- .../competitorimport/CompetitorProvider.java | 28 +++- java/com.sap.sailing.feature/feature.xml | 7 + .../test/CompetitorImportTest.java | 10 +- .../META-INF/MANIFEST.MF | 6 +- .../resultimport/CompetitorImporter.java | 125 +++++++++++------- .../manage2sail/RaceResultDescriptor.java | 72 +++++----- 9 files changed, 174 insertions(+), 92 deletions(-) create mode 100644 java/com.sap.sailing.competitorimport/pom.xml rename java/{com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport => com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport}/CompetitorDescriptor.java (94%) diff --git a/java/com.sap.sailing.competitorimport/META-INF/MANIFEST.MF b/java/com.sap.sailing.competitorimport/META-INF/MANIFEST.MF index 6a9a32014fe..9d271129fcc 100644 --- a/java/com.sap.sailing.competitorimport/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.competitorimport/META-INF/MANIFEST.MF @@ -5,3 +5,6 @@ Bundle-SymbolicName: com.sap.sailing.competitorimport Bundle-Version: 1.0.0.qualifier Bundle-Vendor: SAP Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Export-Package: com.sap.sailing.competitorimport +Require-Bundle: com.sap.sse.common, + com.sap.sailing.domain.shared.android diff --git a/java/com.sap.sailing.competitorimport/pom.xml b/java/com.sap.sailing.competitorimport/pom.xml new file mode 100644 index 00000000000..95d28619b86 --- /dev/null +++ b/java/com.sap.sailing.competitorimport/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + + root + com.sap.sailing + 1.0.0-SNAPSHOT + + com.sap.sailing.competitorimport + eclipse-plugin + diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDescriptor.java b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorDescriptor.java similarity index 94% rename from java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDescriptor.java rename to java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorDescriptor.java index 561e59193c6..2b8576b2ee9 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDescriptor.java +++ b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorDescriptor.java @@ -1,8 +1,9 @@ -package com.sap.sailing.manage2sail.resultimport; +package com.sap.sailing.competitorimport; import com.sap.sailing.domain.base.Person; import com.sap.sse.common.CountryCode; + public class CompetitorDescriptor { private String eventName; private String regattaName; diff --git a/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java index c38dbb5ebc6..f08d3471a4e 100644 --- a/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java +++ b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java @@ -1,5 +1,11 @@ package com.sap.sailing.competitorimport; +import java.io.IOException; +import java.util.Map; +import java.util.Set; + +import javax.xml.bind.JAXBException; + /** * Competitor data may come from various sources, such as external regatta management systems (RMS), * CSV files, Excel spreadsheets and the like. When creating a regatta that uses "RaceLog Tracking" @@ -16,5 +22,25 @@ package com.sap.sailing.competitorimport; * @author Axel Uhl (d043530) * */ -public class CompetitorProvider { +public interface CompetitorProvider { + /** + * @return keys are event names, values are the names of the regatta in the event for which the connector has + * competitor names. Should the value for a key be null, competitors for the event may still + * be available, only they may not be keyed per regatta in that case. + */ + Map> getHasCompetitorsForRegattasInEvent() throws IOException; + + /** + * Obtains competitor records from an XRR file + * + * @param eventName + * an event name as obtained as a key in {@link #getHasCompetitorsForRegattasInEvent()}'s result + * @param regattaName + * null to get the competitors for all regattas in the event specified by + * eventName, or a regatta name as provided in the value set for the key + * eventName as returned by {@link #getHasCompetitorsForRegattasInEvent()}. + * @return + */ + Iterable getCompetitorDescriptors(String eventName, String regattaName) throws JAXBException, + IOException; } diff --git a/java/com.sap.sailing.feature/feature.xml b/java/com.sap.sailing.feature/feature.xml index fc426ce383c..19f3c21c553 100755 --- a/java/com.sap.sailing.feature/feature.xml +++ b/java/com.sap.sailing.feature/feature.xml @@ -470,4 +470,11 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al version="0.0.0" unpack="false"/> + + diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java index 782309c52ee..a8ab2b114ec 100644 --- a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java @@ -1,5 +1,6 @@ package com.sap.sailing.manage2sail.resultimport.test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -12,11 +13,12 @@ import javax.xml.bind.JAXBException; import org.junit.Test; +import com.sap.sailing.competitorimport.CompetitorDescriptor; import com.sap.sailing.manage2sail.resultimport.AbstractManage2SailProvider; -import com.sap.sailing.manage2sail.resultimport.CompetitorDescriptor; import com.sap.sailing.manage2sail.resultimport.CompetitorImporter; import com.sap.sailing.resultimport.ResultUrlRegistry; import com.sap.sailing.xrr.resultimport.ParserFactory; +import com.sap.sse.common.Util; public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { @Test @@ -24,7 +26,11 @@ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource(EVENT_RESULTS_JSON))); final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); - final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors(); + final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors("YES - Young Europeans Sailing 2013", null); // get competitors for all regattas in event assertNotNull(competitorDescriptors); + assertEquals(418, Util.size(competitorDescriptors)); + final Iterable competitorDescriptors29er = competitorImporter.getCompetitorDescriptors("YES - Young Europeans Sailing 2013", "29er"); // get competitors only for 29er regatta + assertNotNull(competitorDescriptors29er); + assertEquals(134, Util.size(competitorDescriptors29er)); } } diff --git a/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF b/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF index ff926200482..48458425411 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.manage2sail.resultimport/META-INF/MANIFEST.MF @@ -6,8 +6,7 @@ Bundle-Version: 1.0.0.qualifier Bundle-Activator: com.sap.sailing.manage2sail.resultimport.Activator Bundle-Vendor: SAP Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: java_cup, - org.osgi.framework;version="1.5.0", +Import-Package: org.osgi.framework;version="1.5.0", org.osgi.util.tracker;version="1.5.1" Bundle-ActivationPolicy: lazy Require-Bundle: com.sap.sailing.manage2sail, @@ -16,4 +15,5 @@ Require-Bundle: com.sap.sailing.manage2sail, com.sap.sailing.xrr.resultimport, com.sap.sse.common, com.sap.sailing.xrr.schema, - com.sap.sailing.domain.shared.android + com.sap.sailing.domain.shared.android, + com.sap.sailing.competitorimport diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java index b30587e63b1..e6acbafd988 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java @@ -2,11 +2,17 @@ package com.sap.sailing.manage2sail.resultimport; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import javax.xml.bind.JAXBException; +import com.sap.sailing.competitorimport.CompetitorDescriptor; +import com.sap.sailing.competitorimport.CompetitorProvider; import com.sap.sailing.domain.base.Nationality; import com.sap.sailing.domain.base.impl.NationalityImpl; import com.sap.sailing.domain.base.impl.PersonImpl; @@ -24,64 +30,85 @@ import com.sap.sailing.xrr.schema.RegattaResults; import com.sap.sailing.xrr.schema.SeriesResult; import com.sap.sailing.xrr.schema.Team; -public class CompetitorImporter extends AbstractManage2SailProvider { +public class CompetitorImporter extends AbstractManage2SailProvider implements CompetitorProvider { private final CompetitorDocumentProvider documentProvider; public CompetitorImporter(ParserFactory parserFactory, ResultUrlRegistry resultUrlRegistry) { super(parserFactory, resultUrlRegistry); documentProvider = new CompetitorDocumentProvider(this); } + + @Override + public Map> getHasCompetitorsForRegattasInEvent() throws IOException { + Map> result = new HashMap<>(); + for (ResultDocumentDescriptor resultDocDescr : documentProvider.getResultDocumentDescriptors()) { + final String eventName = resultDocDescr.getEventName(); + final String regattaName = resultDocDescr.getRegattaName(); + Set set = result.get(eventName); + if (set == null) { + set = new HashSet<>(); + result.put(eventName, set); + } + set.add(regattaName); + } + return result; + } - public Iterable getCompetitorDescriptors() throws JAXBException, IOException { + @Override + public Iterable getCompetitorDescriptors(String eventName, String regattaName) throws JAXBException, IOException { final List result = new ArrayList<>(); for (ResultDocumentDescriptor resultDocDescr : documentProvider.getResultDocumentDescriptors()) { - final Parser parser = getParserFactory().createParser(resultDocDescr.getInputStream(), resultDocDescr.getEventName()); - final RegattaResults regattaResults = parser.parse(); - for (Object o : regattaResults.getPersonOrBoatOrTeam()) { - if (o instanceof Event) { - Event event = (Event) o; - for (Object eventO : event.getRaceOrDivisionOrRegattaSeriesResult()) { - if (eventO instanceof Division) { - Division division = (Division) eventO; - for (Object divisionO : division.getSeriesResultOrRaceResultOrTRResult()) { - String raceID = null; - Team team = null; - if (divisionO instanceof RaceResult) { - RaceResult raceResult = (RaceResult) divisionO; - raceID = raceResult.getRaceID(); - team = parser.getTeam(raceResult.getTeamID()); - } else if (divisionO instanceof SeriesResult) { - SeriesResult seriesResult = (SeriesResult) divisionO; - team = parser.getTeam(seriesResult.getTeamID()); - } - if (team != null) { - final Boat boat = parser.getBoat(team.getBoatID()); - final String sailNumber = boat.getSailNumber(); - final Race race = parser.getRace(raceID); - final Nationality[] teamNationality = new Nationality[] { - // use that of team; if not defined for team, use first nationality of a team member that has one defined - team.getNOC() == null ? null : new NationalityImpl(team.getNOC().name()) - }; - List persons = team.getCrew().stream().sorted((c1, c2) -> -c1.getPosition().name().compareTo(c2.getPosition().name())).map((crew)->{ - Person xrrPerson = parser.getPerson(crew.getPersonID()); - String name = xrrPerson.getGivenName()+" "+xrrPerson.getFamilyName(); - final Nationality nationality; - if (xrrPerson.getNOC() == null) { - nationality = null; - } else { - nationality = new NationalityImpl(xrrPerson.getNOC().name()); - if (teamNationality[0] == null) { - teamNationality[0] = nationality; - } - } - com.sap.sailing.domain.base.Person person = new PersonImpl(name, nationality, /* date of birth */ null, /* description */ xrrPerson.getGender().name()); - return person; - }).collect(Collectors.toList()); - final CompetitorDescriptor competitorDescriptor = new CompetitorDescriptor( - event.getTitle(), division.getTitle() + (division.getGender() == null ? "" : division.getGender().name()), - race != null ? race.getRaceName() : null, /* fleetName */ null, sailNumber, team.getTeamName(), - teamNationality[0] == null ? null : teamNationality[0].getCountryCode(), persons); - result.add(competitorDescriptor); + if (resultDocDescr.getEventName().equals(eventName)) { + final Parser parser = getParserFactory().createParser(resultDocDescr.getInputStream(), resultDocDescr.getEventName()); + final RegattaResults regattaResults = parser.parse(); + for (Object o : regattaResults.getPersonOrBoatOrTeam()) { + if (o instanceof Event) { + Event event = (Event) o; + for (Object eventO : event.getRaceOrDivisionOrRegattaSeriesResult()) { + if (eventO instanceof Division) { + Division division = (Division) eventO; + if (regattaName == null || regattaName.equals(division.getTitle())) { + for (Object divisionO : division.getSeriesResultOrRaceResultOrTRResult()) { + String raceID = null; + Team team = null; + if (divisionO instanceof RaceResult) { + RaceResult raceResult = (RaceResult) divisionO; + raceID = raceResult.getRaceID(); + team = parser.getTeam(raceResult.getTeamID()); + } else if (divisionO instanceof SeriesResult) { + SeriesResult seriesResult = (SeriesResult) divisionO; + team = parser.getTeam(seriesResult.getTeamID()); + } + if (team != null) { + final Boat boat = parser.getBoat(team.getBoatID()); + final String sailNumber = boat.getSailNumber(); + final Race race = parser.getRace(raceID); + final Nationality[] teamNationality = new Nationality[] { + // use that of team; if not defined for team, use first nationality of a team member that has one defined + team.getNOC() == null ? null : new NationalityImpl(team.getNOC().name()) + }; + List persons = team.getCrew().stream().sorted((c1, c2) -> -c1.getPosition().name().compareTo(c2.getPosition().name())).map((crew)->{ + Person xrrPerson = parser.getPerson(crew.getPersonID()); + String name = xrrPerson.getGivenName()+" "+xrrPerson.getFamilyName(); + final Nationality nationality; + if (xrrPerson.getNOC() == null) { + nationality = null; + } else { + nationality = new NationalityImpl(xrrPerson.getNOC().name()); + if (teamNationality[0] == null) { + teamNationality[0] = nationality; + } + } + com.sap.sailing.domain.base.Person person = new PersonImpl(name, nationality, /* date of birth */ null, /* description */ xrrPerson.getGender().name()); + return person; + }).collect(Collectors.toList()); + final CompetitorDescriptor competitorDescriptor = new CompetitorDescriptor( + event.getTitle(), division.getTitle() + (division.getGender() == null ? "" : division.getGender().name()), + race != null ? race.getRaceName() : null, /* fleetName */ null, sailNumber, team.getTeamName(), + teamNationality[0] == null ? null : teamNationality[0].getCountryCode(), persons); + result.add(competitorDescriptor); + } + } } } } diff --git a/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RaceResultDescriptor.java b/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RaceResultDescriptor.java index a98d3eabf3f..6147ed980a9 100644 --- a/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RaceResultDescriptor.java +++ b/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RaceResultDescriptor.java @@ -10,71 +10,71 @@ public class RaceResultDescriptor { private String fleetName; private Boolean isTracked; private Date startTime; - - /** Possible states: Scheduled, StartSequence, Racing, Finished, GeneralRecall, Postponed, Abandoned */ - private String status; + + /** Possible states: Scheduled, StartSequence, Racing, Finished, GeneralRecall, Postponed, Abandoned */ + private String status; public Integer getRaceColumnNumber() { - return raceColumnNumber; - } + return raceColumnNumber; + } public void setRaceColumnNumber(Integer raceColumnNumber) { - this.raceColumnNumber = raceColumnNumber; - } - + this.raceColumnNumber = raceColumnNumber; + } + public String getStatus() { - return status; - } - + return status; + } + public void setStatus(String status) { - this.status = status; - } - + this.status = status; + } + public String getSeriesName() { - return seriesName; - } - + return seriesName; + } + public void setSeriesName(String seriesName) { - this.seriesName = seriesName; - } - + this.seriesName = seriesName; + } + public String getFleetName() { - return fleetName; - } - + return fleetName; + } + public void setFleetName(String fleetName) { - this.fleetName = fleetName; - } + this.fleetName = fleetName; + } public String getId() { return id; } - + public void setId(String id) { this.id = id; } - + public String getName() { return name; } - + public void setName(String name) { this.name = name; } - + public Boolean isTracked() { return isTracked; } - + public void setTracked(Boolean isTracked) { this.isTracked = isTracked; } - public Date getStartTime() { - return startTime; - } + public Date getStartTime() { + return startTime; + } - public void setStartTime(Date startTime) { - this.startTime = startTime; - } + public void setStartTime(Date startTime) { + this.startTime = startTime; + } } From aef0a97fa4d4d832d789063fd0236933d31c138c Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 17:03:52 +0200 Subject: [PATCH 005/214] first test for CompetitorProvider.getHasCompetitorsForRegattasInEvent() API method --- .../manage2sail/resultimport/test/CompetitorImportTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java index a8ab2b114ec..f078f523275 100644 --- a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java @@ -2,6 +2,7 @@ package com.sap.sailing.manage2sail.resultimport.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -26,6 +27,8 @@ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource(EVENT_RESULTS_JSON))); final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); + assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().containsKey("YES - Young Europeans Sailing 2013")); + assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().get("YES - Young Europeans Sailing 2013").contains("29er")); final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors("YES - Young Europeans Sailing 2013", null); // get competitors for all regattas in event assertNotNull(competitorDescriptors); assertEquals(418, Util.size(competitorDescriptors)); From 0fea973b785705b14baf1a469928880e0471dbe5 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 17:05:09 +0200 Subject: [PATCH 006/214] added competitorimport bundle to to-level pom.xml --- java/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/java/pom.xml b/java/pom.xml index 9ae21eaa32d..c16517c066c 100755 --- a/java/pom.xml +++ b/java/pom.xml @@ -34,6 +34,7 @@ com.sap.sse.threadmanager com.sap.sse.filestorage com.sap.sse.gwt.theme + com.sap.sailing.competitorimport com.sap.sailing.domain.common com.sap.sailing.domain.shared.android com.sap.sailing.domain From 22a9288e4af08bbe2332c8cee185862a8aea0510 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 18:01:36 +0200 Subject: [PATCH 007/214] added test material donated by VSaW for a 420 regatta that has competitors but no results yet --- .../resources/VSaW_420_Test.json | 1 + .../resources/VSaW_420_Test.xml | 830 ++++++++++++++++++ 2 files changed, 831 insertions(+) create mode 100644 java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json create mode 100644 java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.xml diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json new file mode 100644 index 00000000000..c2a19230d06 --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json @@ -0,0 +1 @@ +{"Id":"17733a60-305c-4142-98ef-40423449f3be","Name":"IDJM 2015 - 420er","XrrUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta","Regattas":[{"Id":"cd23aa66-81bc-4ae3-ba36-fa03446762b1","Name":"420","Gender":"Open","ClassName":"420","PdfUrl":"","XrrEntriesUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=Entries","XrrPreliminaryUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=PreliminaryResults","XrrFinalUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=FinalResults","HtmlUrl":"http://manage2sail.com/en-US/Home/ResultsFragment/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1"}]} \ No newline at end of file diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.xml b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.xml new file mode 100644 index 00000000000..41f2c54b193 --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.xml @@ -0,0 +1,830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From cf633f2d300ee98905784aa7ffe07e7afeeacf27 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 20:36:06 +0200 Subject: [PATCH 008/214] added test case for competitor import from XRR file with empty division --- .../resources/VSaW_420_Test.json | 2 +- .../VSaW_420_Test_EmptyDivision.json | 1 + .../resources/VSaW_420_Test_EmptyDivision.xml | 729 ++++++++++++++++++ .../test/CompetitorImportTest.java | 26 +- ...ractManage2SailResultDocumentProvider.java | 6 +- .../CompetitorDocumentProvider.java | 12 + .../resultimport/CompetitorImporter.java | 77 +- .../Manage2SailResultDocumentProvider.java | 6 + 8 files changed, 827 insertions(+), 32 deletions(-) create mode 100644 java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json create mode 100644 java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.xml diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json index c2a19230d06..7eba1000800 100644 --- a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json +++ b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json @@ -1 +1 @@ -{"Id":"17733a60-305c-4142-98ef-40423449f3be","Name":"IDJM 2015 - 420er","XrrUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta","Regattas":[{"Id":"cd23aa66-81bc-4ae3-ba36-fa03446762b1","Name":"420","Gender":"Open","ClassName":"420","PdfUrl":"","XrrEntriesUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=Entries","XrrPreliminaryUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=PreliminaryResults","XrrFinalUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=FinalResults","HtmlUrl":"http://manage2sail.com/en-US/Home/ResultsFragment/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1"}]} \ No newline at end of file +{"Id":"17733a60-305c-4142-98ef-40423449f3be","Name":"IDJM 2015 - 420er","XrrUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta","Regattas":[{"Id":"cd23aa66-81bc-4ae3-ba36-fa03446762b1","Name":"420","Gender":"Open","ClassName":"420","PdfUrl":"","XrrEntriesUrl":"file:./bin/VSaW_420_Test.xml","XrrPreliminaryUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=PreliminaryResults","XrrFinalUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=FinalResults","HtmlUrl":"http://manage2sail.com/en-US/Home/ResultsFragment/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1"}]} \ No newline at end of file diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json new file mode 100644 index 00000000000..49ebe47b41c --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json @@ -0,0 +1 @@ +{"Id":"17733a60-305c-4142-98ef-40423449f3be","Name":"IDJM 2015 - 420er","XrrUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta","Regattas":[{"Id":"cd23aa66-81bc-4ae3-ba36-fa03446762b1","Name":"420","Gender":"Open","ClassName":"420","PdfUrl":"","XrrEntriesUrl":"file:./bin/VSaW_420_Test_EmptyDivision.xml","XrrPreliminaryUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=PreliminaryResults","XrrFinalUrl":"http://manage2sail.com/en-US/Home/DownloadXrr/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1?xrrType=FinalResults","HtmlUrl":"http://manage2sail.com/en-US/Home/ResultsFragment/event/17733a60-305c-4142-98ef-40423449f3be/regatta/cd23aa66-81bc-4ae3-ba36-fa03446762b1"}]} \ No newline at end of file diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.xml b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.xml new file mode 100644 index 00000000000..e41a5b1d523 --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.xml @@ -0,0 +1,729 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java index f078f523275..8f27a3a2d11 100644 --- a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java @@ -31,9 +31,33 @@ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().get("YES - Young Europeans Sailing 2013").contains("29er")); final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors("YES - Young Europeans Sailing 2013", null); // get competitors for all regattas in event assertNotNull(competitorDescriptors); - assertEquals(418, Util.size(competitorDescriptors)); + assertEquals(1270, Util.size(competitorDescriptors)); final Iterable competitorDescriptors29er = competitorImporter.getCompetitorDescriptors("YES - Young Europeans Sailing 2013", "29er"); // get competitors only for 29er regatta assertNotNull(competitorDescriptors29er); assertEquals(134, Util.size(competitorDescriptors29er)); } + + @Test + public void simpleCompetitorImportTestNoResultsYet() throws FileNotFoundException, IOException, JAXBException { + ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); + when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test.json"))); + final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); + assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().containsKey("IDJM 2015 - 420er")); + assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().get("IDJM 2015 - 420er").contains("420")); + final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors("IDJM 2015 - 420er", "420"); // get competitors for 420 regatta + assertNotNull(competitorDescriptors); + assertEquals(100, Util.size(competitorDescriptors)); + } + + @Test + public void simpleCompetitorImportTestNoResultsYetAndDivisionEmpty() throws FileNotFoundException, IOException, JAXBException { + ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); + when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test_EmptyDivision.json"))); + final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); + assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().containsKey("IDJM 2015 - 420er")); + assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().get("IDJM 2015 - 420er").contains("420")); + final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors("IDJM 2015 - 420er", null); // get competitors for all regattas in event + assertNotNull(competitorDescriptors); + assertEquals(100, Util.size(competitorDescriptors)); + } } diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java index 16653098c4c..9fec2c4e571 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/AbstractManage2SailResultDocumentProvider.java @@ -43,12 +43,12 @@ public abstract class AbstractManage2SailResultDocumentProvider { // Open boat classes (ORC) -> IFClassID="" Title="Welcome Race ORC-Club" // -> therefore we need to take the regatta title as boat class where the IsafID is not available String boatClass = regattaResult.getIsafId() != null && !regattaResult.getIsafId().isEmpty() ? regattaResult.getIsafId() : regattaResult.getName(); - if (regattaResult.getIsFinal() != null && regattaResult.getPublishedAt() != null) { + if (acceptRegatta(regattaResult)) { final URL resultUrl = getDocumentUrlForRegatta(regattaResult); if (resultUrl != null) { URLConnection regattaResultConn = resultUrl.openConnection(); result.add(new ResultDocumentDescriptorImpl((InputStream) regattaResultConn.getContent(), - resultUrl.toString(), new MillisecondsTimePoint(regattaResult.getPublishedAt()), + resultUrl.toString(), regattaResult.getPublishedAt()==null?null:new MillisecondsTimePoint(regattaResult.getPublishedAt()), eventResult.getName(), regattaResult.getName(), boatClass, regattaResult .getCompetitorGenderType())); } @@ -57,5 +57,7 @@ public abstract class AbstractManage2SailResultDocumentProvider { } } + abstract protected boolean acceptRegatta(RegattaResultDescriptor regattaResult); + abstract protected URL getDocumentUrlForRegatta(RegattaResultDescriptor regattaResult); } diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java index bd6eb782ab1..4968e1b2c7d 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorDocumentProvider.java @@ -1,8 +1,10 @@ package com.sap.sailing.manage2sail.resultimport; +import java.io.IOException; import java.net.URL; import com.sap.sailing.manage2sail.RegattaResultDescriptor; +import com.sap.sailing.resultimport.ResultDocumentDescriptor; import com.sap.sailing.resultimport.ResultUrlProvider; public class CompetitorDocumentProvider extends AbstractManage2SailResultDocumentProvider { @@ -10,8 +12,18 @@ public class CompetitorDocumentProvider extends AbstractManage2SailResultDocumen super(resultUrlProvider); } + @Override + public Iterable getResultDocumentDescriptors() throws IOException { + return super.getResultDocumentDescriptors(); + } + @Override protected URL getDocumentUrlForRegatta(RegattaResultDescriptor regattaResult) { return regattaResult.getXrrEntriesUrl(); } + + @Override + protected boolean acceptRegatta(RegattaResultDescriptor regattaResult) { + return true; // no further requirements; doesn't need to be final nor have an appropriate time point + } } diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java index e6acbafd988..fdcbb14355b 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java @@ -57,12 +57,19 @@ public class CompetitorImporter extends AbstractManage2SailProvider implements C @Override public Iterable getCompetitorDescriptors(String eventName, String regattaName) throws JAXBException, IOException { final List result = new ArrayList<>(); + final Map resultsByTeamID = new HashMap<>(); + final Map teamsWithoutRaceAssignments = new HashMap<>(); for (ResultDocumentDescriptor resultDocDescr : documentProvider.getResultDocumentDescriptors()) { - if (resultDocDescr.getEventName().equals(eventName)) { + if (resultDocDescr.getEventName().equals(eventName) && + (regattaName == null || regattaName.equals(resultDocDescr.getRegattaName()))) { final Parser parser = getParserFactory().createParser(resultDocDescr.getInputStream(), resultDocDescr.getEventName()); final RegattaResults regattaResults = parser.parse(); for (Object o : regattaResults.getPersonOrBoatOrTeam()) { - if (o instanceof Event) { + if (o instanceof Team) { + final Team team = (Team) o; + teamsWithoutRaceAssignments.put(team.getTeamID(), + createCompetitorDescriptor(team, parser, /* event */ null, /* division */ null, /* raceID */ null)); + } else if (o instanceof Event) { Event event = (Event) o; for (Object eventO : event.getRaceOrDivisionOrRegattaSeriesResult()) { if (eventO instanceof Division) { @@ -80,32 +87,9 @@ public class CompetitorImporter extends AbstractManage2SailProvider implements C team = parser.getTeam(seriesResult.getTeamID()); } if (team != null) { - final Boat boat = parser.getBoat(team.getBoatID()); - final String sailNumber = boat.getSailNumber(); - final Race race = parser.getRace(raceID); - final Nationality[] teamNationality = new Nationality[] { - // use that of team; if not defined for team, use first nationality of a team member that has one defined - team.getNOC() == null ? null : new NationalityImpl(team.getNOC().name()) - }; - List persons = team.getCrew().stream().sorted((c1, c2) -> -c1.getPosition().name().compareTo(c2.getPosition().name())).map((crew)->{ - Person xrrPerson = parser.getPerson(crew.getPersonID()); - String name = xrrPerson.getGivenName()+" "+xrrPerson.getFamilyName(); - final Nationality nationality; - if (xrrPerson.getNOC() == null) { - nationality = null; - } else { - nationality = new NationalityImpl(xrrPerson.getNOC().name()); - if (teamNationality[0] == null) { - teamNationality[0] = nationality; - } - } - com.sap.sailing.domain.base.Person person = new PersonImpl(name, nationality, /* date of birth */ null, /* description */ xrrPerson.getGender().name()); - return person; - }).collect(Collectors.toList()); - final CompetitorDescriptor competitorDescriptor = new CompetitorDescriptor( - event.getTitle(), division.getTitle() + (division.getGender() == null ? "" : division.getGender().name()), - race != null ? race.getRaceName() : null, /* fleetName */ null, sailNumber, team.getTeamName(), - teamNationality[0] == null ? null : teamNationality[0].getCountryCode(), persons); + final CompetitorDescriptor competitorDescriptor = createCompetitorDescriptor( + team, parser, event, division, raceID); + resultsByTeamID.put(team.getTeamID(), competitorDescriptor); result.add(competitorDescriptor); } } @@ -116,6 +100,43 @@ public class CompetitorImporter extends AbstractManage2SailProvider implements C } } } + for (final Map.Entry tid : teamsWithoutRaceAssignments.entrySet()) { + if (!resultsByTeamID.containsKey(tid.getKey())) { + result.add(tid.getValue()); + } + } return result; } + + private CompetitorDescriptor createCompetitorDescriptor(Team team, final Parser parser, Event event, + Division division, String raceID) { + final Boat boat = parser.getBoat(team.getBoatID()); + final String sailNumber = boat.getSailNumber(); + final Race race = parser.getRace(raceID); + final Nationality[] teamNationality = new Nationality[] { + // use that of team; if not defined for team, use first nationality of a team member that has one defined + team.getNOC() == null ? null : new NationalityImpl(team.getNOC().name()) + }; + List persons = team.getCrew().stream().sorted((c1, c2) -> -c1.getPosition().name().compareTo(c2.getPosition().name())).map((crew)->{ + Person xrrPerson = parser.getPerson(crew.getPersonID()); + String name = xrrPerson.getGivenName()+" "+xrrPerson.getFamilyName(); + final Nationality nationality; + if (xrrPerson.getNOC() == null) { + nationality = null; + } else { + nationality = new NationalityImpl(xrrPerson.getNOC().name()); + if (teamNationality[0] == null) { + teamNationality[0] = nationality; + } + } + com.sap.sailing.domain.base.Person person = new PersonImpl(name, nationality, /* date of birth */ null, /* description */ xrrPerson.getGender().name()); + return person; + }).collect(Collectors.toList()); + final CompetitorDescriptor competitorDescriptor = new CompetitorDescriptor( + event==null?null:event.getTitle(), + division==null?null:(division.getTitle() + (division.getGender() == null ? "" : division.getGender().name())), + race != null ? race.getRaceName() : null, /* fleetName */ null, sailNumber, team.getTeamName(), + teamNationality[0] == null ? null : teamNationality[0].getCountryCode(), persons); + return competitorDescriptor; + } } diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java index a2cf59735d4..038f6a05ebf 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Manage2SailResultDocumentProvider.java @@ -31,4 +31,10 @@ public class Manage2SailResultDocumentProvider extends AbstractManage2SailResult } return resultUrl; } + + @Override + protected boolean acceptRegatta(RegattaResultDescriptor regattaResult) { + return regattaResult.getIsFinal() != null && regattaResult.getPublishedAt() != null; + } + } From 4d5681c6545c541abcf21e4d7c90db18f358eadc Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Thu, 24 Sep 2015 20:50:06 +0200 Subject: [PATCH 009/214] let class loader compute the URL of the XRR document from the resources/ folder; this should now also work in an OSGi / Surefire environment --- .../test/CompetitorImportTest.java | 28 +++++++++++++- .../resultimport/CompetitorImporter.java | 8 +++- .../Manage2SailEventResultsParserImpl.java | 1 - .../manage2sail/RegattaResultDescriptor.java | 37 +++++++++++++++---- 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java index 8f27a3a2d11..52fc770ca33 100644 --- a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java @@ -8,6 +8,7 @@ import static org.mockito.Mockito.when; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.URL; import java.util.Arrays; import javax.xml.bind.JAXBException; @@ -15,7 +16,10 @@ import javax.xml.bind.JAXBException; import org.junit.Test; import com.sap.sailing.competitorimport.CompetitorDescriptor; +import com.sap.sailing.competitorimport.CompetitorProvider; +import com.sap.sailing.manage2sail.RegattaResultDescriptor; import com.sap.sailing.manage2sail.resultimport.AbstractManage2SailProvider; +import com.sap.sailing.manage2sail.resultimport.CompetitorDocumentProvider; import com.sap.sailing.manage2sail.resultimport.CompetitorImporter; import com.sap.sailing.resultimport.ResultUrlRegistry; import com.sap.sailing.xrr.resultimport.ParserFactory; @@ -41,7 +45,17 @@ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { public void simpleCompetitorImportTestNoResultsYet() throws FileNotFoundException, IOException, JAXBException { ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test.json"))); - final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); + final CompetitorProvider competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry) { + @Override + protected CompetitorDocumentProvider getDocumentProvider() { + return new CompetitorDocumentProvider(this) { + @Override + protected URL getDocumentUrlForRegatta(RegattaResultDescriptor regattaResult) { + return getClass().getClassLoader().getResource("VSaW_420_Test.xml"); + } + }; + } + }; assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().containsKey("IDJM 2015 - 420er")); assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().get("IDJM 2015 - 420er").contains("420")); final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors("IDJM 2015 - 420er", "420"); // get competitors for 420 regatta @@ -53,7 +67,17 @@ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { public void simpleCompetitorImportTestNoResultsYetAndDivisionEmpty() throws FileNotFoundException, IOException, JAXBException { ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test_EmptyDivision.json"))); - final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); + final CompetitorProvider competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry) { + @Override + protected CompetitorDocumentProvider getDocumentProvider() { + return new CompetitorDocumentProvider(this) { + @Override + protected URL getDocumentUrlForRegatta(RegattaResultDescriptor regattaResult) { + return getClass().getClassLoader().getResource("VSaW_420_Test_EmptyDivision.xml"); + } + }; + } + }; assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().containsKey("IDJM 2015 - 420er")); assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().get("IDJM 2015 - 420er").contains("420")); final Iterable competitorDescriptors = competitorImporter.getCompetitorDescriptors("IDJM 2015 - 420er", null); // get competitors for all regattas in event diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java index fdcbb14355b..c32614a1cae 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java @@ -41,7 +41,7 @@ public class CompetitorImporter extends AbstractManage2SailProvider implements C @Override public Map> getHasCompetitorsForRegattasInEvent() throws IOException { Map> result = new HashMap<>(); - for (ResultDocumentDescriptor resultDocDescr : documentProvider.getResultDocumentDescriptors()) { + for (ResultDocumentDescriptor resultDocDescr : getDocumentProvider().getResultDocumentDescriptors()) { final String eventName = resultDocDescr.getEventName(); final String regattaName = resultDocDescr.getRegattaName(); Set set = result.get(eventName); @@ -59,7 +59,7 @@ public class CompetitorImporter extends AbstractManage2SailProvider implements C final List result = new ArrayList<>(); final Map resultsByTeamID = new HashMap<>(); final Map teamsWithoutRaceAssignments = new HashMap<>(); - for (ResultDocumentDescriptor resultDocDescr : documentProvider.getResultDocumentDescriptors()) { + for (ResultDocumentDescriptor resultDocDescr : getDocumentProvider().getResultDocumentDescriptors()) { if (resultDocDescr.getEventName().equals(eventName) && (regattaName == null || regattaName.equals(resultDocDescr.getRegattaName()))) { final Parser parser = getParserFactory().createParser(resultDocDescr.getInputStream(), resultDocDescr.getEventName()); @@ -139,4 +139,8 @@ public class CompetitorImporter extends AbstractManage2SailProvider implements C teamNationality[0] == null ? null : teamNationality[0].getCountryCode(), persons); return competitorDescriptor; } + + protected CompetitorDocumentProvider getDocumentProvider() { + return documentProvider; + } } diff --git a/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/Manage2SailEventResultsParserImpl.java b/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/Manage2SailEventResultsParserImpl.java index 00dc355df69..13739df9aa1 100644 --- a/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/Manage2SailEventResultsParserImpl.java +++ b/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/Manage2SailEventResultsParserImpl.java @@ -31,7 +31,6 @@ public class Manage2SailEventResultsParserImpl implements Manage2SailEventResult /** * @param is closed before the method returns, also in case of exception - * @throws IOException */ public EventResultDescriptor getEventResult(InputStream is) throws IOException { EventResultDescriptor result = null; diff --git a/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RegattaResultDescriptor.java b/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RegattaResultDescriptor.java index 0d9ded55c56..0031067a739 100644 --- a/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RegattaResultDescriptor.java +++ b/java/com.sap.sailing.manage2sail/src/com/sap/sailing/manage2sail/RegattaResultDescriptor.java @@ -26,76 +26,99 @@ public class RegattaResultDescriptor { public RegattaResultDescriptor() { raceResults = new ArrayList(); } - + public String getId() { return id; } + public void setId(String id) { this.id = id; } + public String getIsafId() { return isafId; } + public void setIsafId(String isafId) { this.isafId = isafId; } + public String getExternalId() { return externalId; } + public void setExternalId(String externalId) { this.externalId = externalId; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } + public String getClassName() { return className; } + public void setClassName(String className) { this.className = className; } + public URL getPdfUrl() { return pdfUrl; } + public void setPdfUrl(URL pdfUrl) { this.pdfUrl = pdfUrl; } + public URL getXrrPreliminaryUrl() { return xrrPreliminaryUrl; } + public void setXrrPreliminaryUrl(URL xrrPreliminaryUrl) { this.xrrPreliminaryUrl = xrrPreliminaryUrl; } + public URL getXrrFinalUrl() { return xrrFinalUrl; } + public void setXrrFinalUrl(URL xrrFinalUrl) { this.xrrFinalUrl = xrrFinalUrl; } + public URL getHtmlUrl() { return htmlUrl; } + public void setHtmlUrl(URL htmlUrl) { this.htmlUrl = htmlUrl; } + public Date getPublishedAt() { return publishedAt; } + public void setPublishedAt(Date publishedAt) { this.publishedAt = publishedAt; } + public Boolean getIsFinal() { return isFinal; } + public void setIsFinal(Boolean isFinal) { this.isFinal = isFinal; } + public CompetitorGenderType getCompetitorGenderType() { return competitorGenderType; } + public void setCompetitorGenderType(CompetitorGenderType competitorGenderType) { this.competitorGenderType = competitorGenderType; } @@ -108,11 +131,11 @@ public class RegattaResultDescriptor { this.raceResults = raceResults; } - public URL getXrrEntriesUrl() { - return xrrEntriesUrl; - } + public URL getXrrEntriesUrl() { + return xrrEntriesUrl; + } - public void setXrrEntriesUrl(URL xrrEntriesUrl) { - this.xrrEntriesUrl = xrrEntriesUrl; - } + public void setXrrEntriesUrl(URL xrrEntriesUrl) { + this.xrrEntriesUrl = xrrEntriesUrl; + } } From 383f342ffc4d51a7e298041e135ec445cb9d1afb Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 2 Oct 2015 16:13:03 +0200 Subject: [PATCH 010/214] renamed .json test resources to .json.txt to force a non-null content-type for a BundleURLConnection during execution in Maven --- ...SaW_420_Test.json => VSaW_420_Test.json.txt} | 0 ...son => VSaW_420_Test_EmptyDivision.json.txt} | 0 .../resources/eventResults.json.txt | 1 + .../resultimport/test/CompetitorImportTest.java | 17 ++++++++++++++--- 4 files changed, 15 insertions(+), 3 deletions(-) rename java/com.sap.sailing.manage2sail.resultimport.test/resources/{VSaW_420_Test.json => VSaW_420_Test.json.txt} (100%) rename java/com.sap.sailing.manage2sail.resultimport.test/resources/{VSaW_420_Test_EmptyDivision.json => VSaW_420_Test_EmptyDivision.json.txt} (100%) create mode 100644 java/com.sap.sailing.manage2sail.resultimport.test/resources/eventResults.json.txt diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json.txt similarity index 100% rename from java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json rename to java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test.json.txt diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json b/java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json.txt similarity index 100% rename from java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json rename to java/com.sap.sailing.manage2sail.resultimport.test/resources/VSaW_420_Test_EmptyDivision.json.txt diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/resources/eventResults.json.txt b/java/com.sap.sailing.manage2sail.resultimport.test/resources/eventResults.json.txt new file mode 100644 index 00000000000..c37cdbec30d --- /dev/null +++ b/java/com.sap.sailing.manage2sail.resultimport.test/resources/eventResults.json.txt @@ -0,0 +1 @@ +{"Id":"58f73e6c-ec07-4655-972c-e5d730f0048e","Name":"YES - Young Europeans Sailing 2013","IsafId":null,"XrrUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta","Regattas":[{"Id":"14a09b88-3d45-43be-be74-cb9083484099","IsafId":"29ER","ExternalId":null,"Name":"29er","ClassName":"29er","PdfUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadReport/event/58f73e6c-ec07-4655-972c-e5d730f0048e/report/6a424c3b-bce4-4a56-a339-567e25a3bce2","XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/14a09b88-3d45-43be-be74-cb9083484099?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/14a09b88-3d45-43be-be74-cb9083484099?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/14a09b88-3d45-43be-be74-cb9083484099?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/14a09b88-3d45-43be-be74-cb9083484099","Published":"2013-06-10T13:37:57.956+02:00","Final":false},{"Id":"71a5fcc2-8d2f-43c8-84ad-2919f788fbbb","IsafId":null,"ExternalId":null,"Name":"29erXX","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/71a5fcc2-8d2f-43c8-84ad-2919f788fbbb?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/71a5fcc2-8d2f-43c8-84ad-2919f788fbbb?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/71a5fcc2-8d2f-43c8-84ad-2919f788fbbb?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/71a5fcc2-8d2f-43c8-84ad-2919f788fbbb","Published":null,"Final":false},{"Id":"a4d93eb6-aac3-4423-ac1e-b761cc98ac09","IsafId":"420","ExternalId":null,"Name":"420","ClassName":"420","PdfUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadReport/event/58f73e6c-ec07-4655-972c-e5d730f0048e/report/93224d94-0350-4c92-97e2-3b203f491bcc","XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/a4d93eb6-aac3-4423-ac1e-b761cc98ac09?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/a4d93eb6-aac3-4423-ac1e-b761cc98ac09?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/a4d93eb6-aac3-4423-ac1e-b761cc98ac09?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/a4d93eb6-aac3-4423-ac1e-b761cc98ac09","Published":"2013-05-28T11:44:06.759+02:00","Final":false},{"Id":"bfe3260d-1ca1-418d-ac92-f1bd17b14df8","IsafId":null,"ExternalId":null,"Name":"470 (German Junior Championship)","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bfe3260d-1ca1-418d-ac92-f1bd17b14df8?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bfe3260d-1ca1-418d-ac92-f1bd17b14df8?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bfe3260d-1ca1-418d-ac92-f1bd17b14df8?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bfe3260d-1ca1-418d-ac92-f1bd17b14df8","Published":null,"Final":false},{"Id":"bc5b3773-a88b-450b-bac1-fecb79aa836c","IsafId":null,"ExternalId":null,"Name":"505","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bc5b3773-a88b-450b-bac1-fecb79aa836c?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bc5b3773-a88b-450b-bac1-fecb79aa836c?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bc5b3773-a88b-450b-bac1-fecb79aa836c?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/bc5b3773-a88b-450b-bac1-fecb79aa836c","Published":null,"Final":false},{"Id":"360f04fa-d06f-4bae-a858-ee4aa6ca1aa0","IsafId":null,"ExternalId":null,"Name":"Europe","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/360f04fa-d06f-4bae-a858-ee4aa6ca1aa0?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/360f04fa-d06f-4bae-a858-ee4aa6ca1aa0?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/360f04fa-d06f-4bae-a858-ee4aa6ca1aa0?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/360f04fa-d06f-4bae-a858-ee4aa6ca1aa0","Published":null,"Final":false},{"Id":"81856d12-5491-4344-95b7-fcb5a2d021fb","IsafId":null,"ExternalId":null,"Name":"int. 14-Footer","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/81856d12-5491-4344-95b7-fcb5a2d021fb?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/81856d12-5491-4344-95b7-fcb5a2d021fb?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/81856d12-5491-4344-95b7-fcb5a2d021fb?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/81856d12-5491-4344-95b7-fcb5a2d021fb","Published":null,"Final":false},{"Id":"37c09f65-7a18-4f83-baac-460471f5b165","IsafId":null,"ExternalId":null,"Name":"Laser Std. - M (German Junior Championship)","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/37c09f65-7a18-4f83-baac-460471f5b165?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/37c09f65-7a18-4f83-baac-460471f5b165?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/37c09f65-7a18-4f83-baac-460471f5b165?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/37c09f65-7a18-4f83-baac-460471f5b165","Published":null,"Final":false},{"Id":"50a8e62a-e33d-4d6b-8007-908213b15ba0","IsafId":null,"ExternalId":null,"Name":"Laser Std. - W","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/50a8e62a-e33d-4d6b-8007-908213b15ba0?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/50a8e62a-e33d-4d6b-8007-908213b15ba0?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/50a8e62a-e33d-4d6b-8007-908213b15ba0?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/50a8e62a-e33d-4d6b-8007-908213b15ba0","Published":null,"Final":false},{"Id":"fc538447-3516-47d1-aece-9d52058cae76","IsafId":null,"ExternalId":null,"Name":"Laser Rad. - W (German Junior Championship)","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/fc538447-3516-47d1-aece-9d52058cae76?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/fc538447-3516-47d1-aece-9d52058cae76?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/fc538447-3516-47d1-aece-9d52058cae76?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/fc538447-3516-47d1-aece-9d52058cae76","Published":null,"Final":false},{"Id":"c0cf4ab8-e79d-4e72-8006-973c743fd316","IsafId":null,"ExternalId":null,"Name":"Laser Rad. - M","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c0cf4ab8-e79d-4e72-8006-973c743fd316?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c0cf4ab8-e79d-4e72-8006-973c743fd316?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c0cf4ab8-e79d-4e72-8006-973c743fd316?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c0cf4ab8-e79d-4e72-8006-973c743fd316","Published":null,"Final":false},{"Id":"42230139-32e8-4b54-aa05-f89da352f351","IsafId":null,"ExternalId":null,"Name":"Laser 4.7","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/42230139-32e8-4b54-aa05-f89da352f351?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/42230139-32e8-4b54-aa05-f89da352f351?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/42230139-32e8-4b54-aa05-f89da352f351?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/42230139-32e8-4b54-aa05-f89da352f351","Published":null,"Final":false},{"Id":"c41d591d-ff2a-4de4-be68-0be86816bc1d","IsafId":null,"ExternalId":null,"Name":"Pirat","ClassName":"Pirate","PdfUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadReport/event/58f73e6c-ec07-4655-972c-e5d730f0048e/report/17003ef7-119d-44d7-bd09-ade3c241a879","XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c41d591d-ff2a-4de4-be68-0be86816bc1d?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c41d591d-ff2a-4de4-be68-0be86816bc1d?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c41d591d-ff2a-4de4-be68-0be86816bc1d?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/c41d591d-ff2a-4de4-be68-0be86816bc1d","Published":"2013-06-06T16:45:16.257+02:00","Final":false},{"Id":"21af6a6c-3128-48d0-afa7-479b627a575d","IsafId":null,"ExternalId":null,"Name":"Coachboat","ClassName":null,"PdfUrl":null,"XrrEntriesUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/21af6a6c-3128-48d0-afa7-479b627a575d?xrrType=Entries","XrrPreliminaryUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/21af6a6c-3128-48d0-afa7-479b627a575d?xrrType=PreliminaryResults","XrrFinalUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/Home/DownloadXrr/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/21af6a6c-3128-48d0-afa7-479b627a575d?xrrType=FinalResults","HtmlUrl":"https://orm.manage2sail.com/shadowtest_info/en-US/resultsFragment/event/58f73e6c-ec07-4655-972c-e5d730f0048e/regatta/21af6a6c-3128-48d0-afa7-479b627a575d","Published":null,"Final":false}]} \ No newline at end of file diff --git a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java index 52fc770ca33..ae9d939b733 100644 --- a/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java +++ b/java/com.sap.sailing.manage2sail.resultimport.test/src/com/sap/sailing/manage2sail/resultimport/test/CompetitorImportTest.java @@ -25,11 +25,22 @@ import com.sap.sailing.resultimport.ResultUrlRegistry; import com.sap.sailing.xrr.resultimport.ParserFactory; import com.sap.sse.common.Util; +/** + * The Bundle URL connection implementation is really stupid; it doesn't recognize a content type for files exposed by + * a "bundleresource://" URL. We need to disguise the JSON documents as ".txt" documents for the purpose of this test + * to allow for the bundle resource class loader to find them.

+ * + * Ironically, in an Eclipse-based test environment everything seems fine. The problem occurs when a compiled bundle + * as a JAR file is loaded by an OSGi execution environment, such as during the Maven / Surefire tests. + * + * @author Axel Uhl (d043530) + * + */ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { @Test public void simpleCompetitorImportTest() throws FileNotFoundException, IOException, JAXBException { ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); - when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource(EVENT_RESULTS_JSON))); + when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource(EVENT_RESULTS_JSON+".txt"))); final CompetitorImporter competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry); assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().containsKey("YES - Young Europeans Sailing 2013")); assertTrue(competitorImporter.getHasCompetitorsForRegattasInEvent().get("YES - Young Europeans Sailing 2013").contains("29er")); @@ -44,7 +55,7 @@ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { @Test public void simpleCompetitorImportTestNoResultsYet() throws FileNotFoundException, IOException, JAXBException { ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); - when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test.json"))); + when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test.json.txt"))); final CompetitorProvider competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry) { @Override protected CompetitorDocumentProvider getDocumentProvider() { @@ -66,7 +77,7 @@ public class CompetitorImportTest extends AbstractEventResultJsonServiceTest { @Test public void simpleCompetitorImportTestNoResultsYetAndDivisionEmpty() throws FileNotFoundException, IOException, JAXBException { ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); - when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test_EmptyDivision.json"))); + when(resultUrlRegistry.getResultUrls(AbstractManage2SailProvider.NAME)).thenReturn(Arrays.asList(getClass().getClassLoader().getResource("VSaW_420_Test_EmptyDivision.json.txt"))); final CompetitorProvider competitorImporter = new CompetitorImporter(ParserFactory.INSTANCE, resultUrlRegistry) { @Override protected CompetitorDocumentProvider getDocumentProvider() { From e59eec230e68d0a1b53ddfed0b09bf90673be297 Mon Sep 17 00:00:00 2001 From: Alexander Tatarinovich Date: Tue, 1 Nov 2016 09:16:55 +0300 Subject: [PATCH 011/214] bug3246: Competitor import (without saving competitors in store yet) Change-Id: I2eb77445a1a3264bcc9ae97248e81563ca031748 --- .../competitorimport/CompetitorProvider.java | 4 +- .../common/dto/CompetitorDescriptorDTO.java | 135 +++++++++ .../sailing/domain/common/dto/PersonDTO.java | 67 +++++ .../META-INF/MANIFEST.MF | 3 +- .../ApplyImportedCompetitorsDialog.java | 172 +++++++++++ .../gwt/ui/adminconsole/BusynessPanel.java | 10 + .../CompetitorDescriptorTableWrapper.java | 197 +++++++++++++ .../CompetitorImportDialogResult.java | 35 +++ .../adminconsole/CompetitorImportMatcher.java | 50 ++++ ...mpetitorImportProviderSelectionDialog.java | 270 ++++++++++++++++++ .../gwt/ui/adminconsole/CompetitorPanel.java | 58 +++- .../sailing/gwt/ui/client/SailingService.java | 9 + .../gwt/ui/client/SailingServiceAsync.java | 9 + .../sailing/gwt/ui/client/StringMessages.java | 9 + .../gwt/ui/client/StringMessages.properties | 9 + .../gwt/ui/server/SailingServiceImpl.java | 99 +++++++ .../gwt/ui/shared/CompetitorProviderDTO.java | 46 +++ .../manage2sail/resultimport/Activator.java | 8 + .../resultimport/CompetitorImporter.java | 5 + .../META-INF/MANIFEST.MF | 3 +- ...ltUrlRegistryServiceTrackerCustomizer.java | 14 + 21 files changed, 1208 insertions(+), 4 deletions(-) create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/BusynessPanel.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java diff --git a/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java index f08d3471a4e..44f871ddc35 100644 --- a/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java +++ b/java/com.sap.sailing.competitorimport/src/com/sap/sailing/competitorimport/CompetitorProvider.java @@ -5,6 +5,8 @@ import java.util.Map; import java.util.Set; import javax.xml.bind.JAXBException; +import com.sap.sailing.competitorimport.CompetitorDescriptor; +import com.sap.sse.common.Named; /** * Competitor data may come from various sources, such as external regatta management systems (RMS), @@ -22,7 +24,7 @@ import javax.xml.bind.JAXBException; * @author Axel Uhl (d043530) * */ -public interface CompetitorProvider { +public interface CompetitorProvider extends Named{ /** * @return keys are event names, values are the names of the regatta in the event for which the connector has * competitor names. Should the value for a key be null, competitors for the event may still diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java new file mode 100644 index 00000000000..6a9e77e8b9b --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java @@ -0,0 +1,135 @@ +package com.sap.sailing.domain.common.dto; + +import java.util.Objects; +import java.util.Set; + +public class CompetitorDescriptorDTO extends NamedDTO { + private static final long serialVersionUID = 4855053239521181610L; + private String eventName; + private String regattaName; + private String raceName; + private String fleetName; + private String sailNumber; + + private String countryName; + private String twoLetterIsoCountryCode; + private String threeLetterIocCountryCode; + + private Set persons; + + public CompetitorDescriptorDTO() { + } + + public CompetitorDescriptorDTO(String eventName, String regattaName, String raceName, String fleetName, + String sailNumber, String competitorName, String countryName, String twoLetterIsoCountryCode, + String threeLetterIocCountryCode, Set persons) { + super(competitorName); + this.eventName = eventName; + this.regattaName = regattaName; + this.raceName = raceName; + this.fleetName = fleetName; + this.sailNumber = sailNumber; + this.countryName = countryName; + this.twoLetterIsoCountryCode = twoLetterIsoCountryCode; + this.threeLetterIocCountryCode = threeLetterIocCountryCode; + this.persons = persons; + } + + public String getEventName() { + return eventName; + } + + public void setEventName(String eventName) { + this.eventName = eventName; + } + + public String getRegattaName() { + return regattaName; + } + + public void setRegattaName(String regattaName) { + this.regattaName = regattaName; + } + + public String getRaceName() { + return raceName; + } + + public void setRaceName(String raceName) { + this.raceName = raceName; + } + + public String getFleetName() { + return fleetName; + } + + public void setFleetName(String fleetName) { + this.fleetName = fleetName; + } + + public String getSailNumber() { + return sailNumber; + } + + public void setSailNumber(String sailNumber) { + this.sailNumber = sailNumber; + } + + public Iterable getPersons() { + return persons; + } + + public void setPersons(Set persons) { + this.persons = persons; + } + + public String getCountryName() { + return countryName; + } + + public void setCountryName(String countryName) { + this.countryName = countryName; + } + + public String getTwoLetterIsoCountryCode() { + return twoLetterIsoCountryCode; + } + + public void setTwoLetterIsoCountryCode(String twoLetterIsoCountryCode) { + this.twoLetterIsoCountryCode = twoLetterIsoCountryCode; + } + + public String getThreeLetterIocCountryCode() { + return threeLetterIocCountryCode; + } + + public void setThreeLetterIocCountryCode(String threeLetterIocCountryCode) { + this.threeLetterIocCountryCode = threeLetterIocCountryCode; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Objects.hash(eventName, regattaName, raceName, fleetName, sailNumber, persons, + countryName, twoLetterIsoCountryCode, threeLetterIocCountryCode); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + CompetitorDescriptorDTO other = (CompetitorDescriptorDTO) obj; + return Objects.equals(countryName, other.countryName) && Objects.equals(eventName, other.eventName) + && Objects.equals(fleetName, other.fleetName) && Objects.deepEquals(persons, other.persons) + && Objects.equals(raceName, other.raceName) && Objects.equals(regattaName, other.regattaName) + && Objects.equals(sailNumber, other.sailNumber) + && Objects.equals(threeLetterIocCountryCode, other.threeLetterIocCountryCode) + && Objects.equals(twoLetterIsoCountryCode, other.twoLetterIsoCountryCode); + } +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java new file mode 100644 index 00000000000..ffe19c6c193 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java @@ -0,0 +1,67 @@ +package com.sap.sailing.domain.common.dto; + +import java.util.Date; +import java.util.Objects; + +public class PersonDTO extends NamedDTO { + private static final long serialVersionUID = 7248019801310303654L; + private Date dateOfBirth; + private String description; + private String nationalityThreeLetterIOCAcronym; + + public PersonDTO() { + } + + public PersonDTO(String name, Date dateOfBirth, String description, String nationalityThreeLetterIOCAcronym) { + super(name); + this.dateOfBirth = dateOfBirth; + this.description = description; + this.nationalityThreeLetterIOCAcronym = nationalityThreeLetterIOCAcronym; + } + + public Date getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(Date dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getNationalityThreeLetterIOCAcronym() { + return nationalityThreeLetterIOCAcronym; + } + + public void setNationalityThreeLetterIOCAcronym(String nationalityThreeLetterIOCAcronym) { + this.nationalityThreeLetterIOCAcronym = nationalityThreeLetterIOCAcronym; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Objects.hash(dateOfBirth, description, nationalityThreeLetterIOCAcronym); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + + PersonDTO other = (PersonDTO) obj; + return Objects.equals(dateOfBirth, other.dateOfBirth) && Objects.equals(description, other.description) + && Objects.equals(nationalityThreeLetterIOCAcronym, other.nationalityThreeLetterIOCAcronym); + } +} diff --git a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF index 8cfb13530f1..b57f7f43481 100644 --- a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF @@ -51,7 +51,8 @@ Require-Bundle: com.sap.sailing.domain, com.sap.sailing.polars.datamining.shared, com.sap.sailing.polars.datamining, com.sap.sse.datamining.annotations, - com.sap.sse.shared.android + com.sap.sse.shared.android, + com.sap.sailing.competitorimport Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator Bundle-ActivationPolicy: lazy Import-Package: javax.servlet;version="3.1.0", diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java new file mode 100644 index 00000000000..9d3917f5286 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java @@ -0,0 +1,172 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.google.gwt.user.client.ui.CaptionPanel; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.Widget; +import com.google.gwt.view.client.SelectionChangeEvent; +import com.google.gwt.view.client.SelectionChangeEvent.Handler; +import com.sap.sailing.domain.common.dto.BoatDTO; +import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorDTOImpl; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.gwt.client.ErrorReporter; +import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel; +import com.sap.sse.gwt.client.celltable.RefreshableSingleSelectionModel; +import com.sap.sse.gwt.client.dialog.DataEntryDialog; + +/** + * Define dialog where we can match and apply imported competitors. + * + * @author Alexander_Tatarinovich + * + */ +public class ApplyImportedCompetitorsDialog extends DataEntryDialog> { + + private CompetitorDescriptorTableWrapper> importedCompetitorsTable; + private CompetitorTableWrapper> existingCompetitorsTable; + + private final StringMessages stringMessages; + private final SailingServiceAsync sailingService; + private final ErrorReporter errorReporter; + + private final Iterable competitorDescriptorDTOs; + private final CompetitorImportMatcher competitorImportMatcher; + + private final Map existingCompetitorsByImported = new HashMap<>(); + + public ApplyImportedCompetitorsDialog(final Iterable competitorDescriptorDTOs, + final Iterable existingCompetitor, StringMessages stringMessages, + SailingServiceAsync sailingService, ErrorReporter errorReporter) { + super(stringMessages.importCompetitors(), stringMessages.choseWhichCompetitorsShouldBeImported(), + stringMessages.ok(), stringMessages.cancel(), null, /* TODO: implement calback */null); + this.stringMessages = stringMessages; + this.sailingService = sailingService; + this.errorReporter = errorReporter; + this.competitorDescriptorDTOs = competitorDescriptorDTOs; + competitorImportMatcher = new CompetitorImportMatcher(existingCompetitor); + } + + @Override + protected Widget getAdditionalWidget() { + existingCompetitorsTable = new CompetitorTableWrapper<>(sailingService, stringMessages, + errorReporter, /* multiSelection */ + false, /* enablePager */true); + importedCompetitorsTable = new CompetitorDescriptorTableWrapper<>(competitorImportMatcher, sailingService, + stringMessages, errorReporter, /* multiSelection */ + true, /* enablePager */false); + importedCompetitorsTable.refreshCompetitorDescriptorList(competitorDescriptorDTOs); + + final RefreshableMultiSelectionModel importedCompetitorSelectionModel = importedCompetitorsTable + .getSelectionModel(); + importedCompetitorSelectionModel + .addSelectionChangeHandler(getHandlerForImportedCompetitorsModel(importedCompetitorSelectionModel)); + + final RefreshableSingleSelectionModel existingCompetitorSelectionModel = existingCompetitorsTable + .getSelectionModel(); + existingCompetitorSelectionModel.addSelectionChangeHandler(getHandlerForExistingCompetitorsModel( + importedCompetitorSelectionModel, existingCompetitorSelectionModel)); + + final FlowPanel mainPanel = new FlowPanel(); + final HorizontalPanel competitorImportPanel = new HorizontalPanel(); + final CaptionPanel existingCompetitorsPanel = new CaptionPanel(stringMessages.existingCompetitors()); + final CaptionPanel importedCompetitorsPanel = new CaptionPanel(stringMessages.importedCompetitors()); + + existingCompetitorsPanel.add(existingCompetitorsTable); + importedCompetitorsPanel.add(importedCompetitorsTable); + + ScrollPanel scrollCompetitorRegistrationPanel = new ScrollPanel(importedCompetitorsPanel); + scrollCompetitorRegistrationPanel.setSize("100%", "500px"); + ScrollPanel scrollExistingCompetitorRegistrationPanel = new ScrollPanel(existingCompetitorsPanel); + scrollCompetitorRegistrationPanel.setSize("100%", "500px"); + competitorImportPanel.add(scrollCompetitorRegistrationPanel); + competitorImportPanel.add(scrollExistingCompetitorRegistrationPanel); + + mainPanel.add(competitorImportPanel); + return mainPanel; + } + + private Handler getHandlerForExistingCompetitorsModel( + final RefreshableMultiSelectionModel importedCompetitorSelectionModel, + final RefreshableSingleSelectionModel existingCompetitorSelectionModel) { + return new Handler() { + @Override + public void onSelectionChange(SelectionChangeEvent event) { + Set competitorDescriptors = importedCompetitorSelectionModel.getSelectedSet(); + if (competitorDescriptors.size() > 1) { + return; + } + CompetitorDTO selectedCompetitor = existingCompetitorSelectionModel.getSelectedObject(); + CompetitorDescriptorDTO selectedCompetitorDescriptor = competitorDescriptors.isEmpty() ? null + : importedCompetitorSelectionModel.getSelectedSet().iterator().next(); + if (selectedCompetitorDescriptor != null) { + existingCompetitorsByImported.put(selectedCompetitorDescriptor, selectedCompetitor); + } + } + }; + } + + private Handler getHandlerForImportedCompetitorsModel( + final RefreshableMultiSelectionModel importedCompetitorSelectionModel) { + return new Handler() { + @Override + public void onSelectionChange(SelectionChangeEvent event) { + Set selectedCompetitorDescriptors = importedCompetitorSelectionModel + .getSelectedSet(); + if (selectedCompetitorDescriptors.size() > 1) { + existingCompetitorsTable.getFilterField().removeAll(); + return; + } + + CompetitorDescriptorDTO selectedCompetitorDescriptor = selectedCompetitorDescriptors.isEmpty() ? null + : importedCompetitorSelectionModel.getSelectedSet().iterator().next(); + existingCompetitorsTable.refreshCompetitorList( + competitorImportMatcher.getMatchesCompetitors(selectedCompetitorDescriptor)); + CompetitorDTO competitor = existingCompetitorsByImported.get(selectedCompetitorDescriptor); + if (competitor != null) { + existingCompetitorsTable.getSelectionModel().setSelected(competitor, true); + } + } + }; + } + + private void saveCompetitors(Set competitors) { + // TODO: implement logic for saving competitors + + registerCompetitors(competitors); + } + + protected void registerCompetitors(Set competitors) { + // Do nothing by default. Can be overridden in child classes for registration competitor in race or regatta + } + + @Override + protected Set getResult() { + final Set competitorsForSave = new HashSet<>(); + for (CompetitorDescriptorDTO competitorDescriptor : importedCompetitorsTable.getSelectionModel() + .getSelectedSet()) { + CompetitorDTO existingCompetitor = existingCompetitorsByImported.get(competitorDescriptor); + if (existingCompetitor != null) { + competitorsForSave.add(existingCompetitor); + } else { + competitorsForSave.add(convertCompetitorDescriptorToCompetitorDTO(competitorDescriptor)); + } + } + return competitorsForSave; + } + + private CompetitorDTO convertCompetitorDescriptorToCompetitorDTO(CompetitorDescriptorDTO competitorDescriptor) { + BoatDTO boat = new BoatDTO(null, competitorDescriptor.getSailNumber()); + return new CompetitorDTOImpl(competitorDescriptor.getName(), null, null, + competitorDescriptor.getTwoLetterIsoCountryCode(), competitorDescriptor.getThreeLetterIocCountryCode(), + competitorDescriptor.getCountryName(), null, null, null, boat, null, null, null, null); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/BusynessPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/BusynessPanel.java new file mode 100644 index 00000000000..0023b14ab0d --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/BusynessPanel.java @@ -0,0 +1,10 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +/** + * Declare that panel can be busy when some actions are performed. + * + * @author Alexander_Tatarinovich + */ +public interface BusynessPanel { + void setBusy(boolean isBusy); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java new file mode 100644 index 00000000000..1651d8eb4b0 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java @@ -0,0 +1,197 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import java.util.ArrayList; +import java.util.Comparator; + +import java.util.List; + +import com.google.gwt.cell.client.SafeHtmlCell; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.safehtml.shared.SafeHtml; +import com.google.gwt.safehtml.shared.SafeHtmlBuilder; +import com.google.gwt.user.cellview.client.Column; +import com.google.gwt.user.cellview.client.TextColumn; +import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; +import com.google.gwt.user.client.ui.ImageResourceRenderer; +import com.google.gwt.user.client.ui.Label; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; +import com.sap.sailing.gwt.ui.client.FlagImageResolver; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.common.util.NaturalComparator; +import com.sap.sse.gwt.client.ErrorReporter; +import com.sap.sse.gwt.client.celltable.EntityIdentityComparator; +import com.sap.sse.gwt.client.celltable.RefreshableSelectionModel; +import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel; + +public class CompetitorDescriptorTableWrapper> + extends TableWrapper { + + private final LabeledAbstractFilterablePanel filterablePanelCompetitorDescriptor; + + private final CompetitorImportMatcher competitorImportMatcher; + + public CompetitorDescriptorTableWrapper(CompetitorImportMatcher competitorImportMatcherParam, + SailingServiceAsync sailingService, final StringMessages stringMessages, ErrorReporter errorReporter, + boolean multiSelection, boolean enablePager) { + super(sailingService, stringMessages, errorReporter, multiSelection, enablePager, + new EntityIdentityComparator() { + @Override + public boolean representSameEntity(CompetitorDescriptorDTO dto1, CompetitorDescriptorDTO dto2) { + return dto1.equals(dto2); + } + + @Override + public int hashCode(CompetitorDescriptorDTO dto) { + return dto.hashCode(); + } + }); + + this.competitorImportMatcher = competitorImportMatcherParam; + + filterablePanelCompetitorDescriptor = new LabeledAbstractFilterablePanel( + new Label(stringMessages.filterImportedCompetitorsByNameSailRaceFleet()), + new ArrayList(), table, dataProvider) { + @Override + public Iterable getSearchableStrings(CompetitorDescriptorDTO competitorDescriptor) { + List string = new ArrayList(); + string.add(competitorDescriptor.getName()); + string.add(competitorDescriptor.getSailNumber()); + string.add(competitorDescriptor.getRaceName()); + string.add(competitorDescriptor.getFleetName()); + return string; + } + }; + registerSelectionModelOnNewDataProvider(filterablePanelCompetitorDescriptor.getAllListDataProvider()); + + TextColumn competitorNameColumn = new TextColumn() { + @Override + public String getValue(CompetitorDescriptorDTO competitor) { + return competitor.getName(); + } + }; + competitorNameColumn.setSortable(true); + + Column sailIdColumn = new Column( + new SafeHtmlCell()) { + @Override + public SafeHtml getValue(CompetitorDescriptorDTO competitor) { + SafeHtmlBuilder sb = new SafeHtmlBuilder(); + ImageResourceRenderer renderer = new ImageResourceRenderer(); + final String twoLetterIsoCountryCode = competitor.getTwoLetterIsoCountryCode(); + + final ImageResource flagImageResource; + if (twoLetterIsoCountryCode == null || twoLetterIsoCountryCode.isEmpty()) { + flagImageResource = FlagImageResolver.getEmptyFlagImageResource(); + } else { + flagImageResource = FlagImageResolver.getFlagImageResource(twoLetterIsoCountryCode); + } + if (flagImageResource != null) { + sb.append(renderer.render(flagImageResource)); + sb.appendHtmlConstant(" "); + } + + sb.appendEscaped(competitor.getSailNumber()); + return sb.toSafeHtml(); + } + }; + sailIdColumn.setSortable(true); + + TextColumn raceNameColumn = new TextColumn() { + @Override + public String getValue(CompetitorDescriptorDTO competitorDescriptor) { + return competitorDescriptor.getRaceName(); + } + }; + raceNameColumn.setSortable(true); + + TextColumn fleetNameColumn = new TextColumn() { + @Override + public String getValue(CompetitorDescriptorDTO competitorDescriptor) { + return competitorDescriptor.getFleetName(); + } + }; + fleetNameColumn.setSortable(true); + + TextColumn isHasMatchesColumn = new TextColumn() { + @Override + public String getValue(CompetitorDescriptorDTO competitorDescriptor) { + return competitorImportMatcher.getMatchesCompetitors(competitorDescriptor).isEmpty() + ? stringMessages.no() : stringMessages.yes(); + } + }; + isHasMatchesColumn.setSortable(true); + + mainPanel.insert(filterablePanelCompetitorDescriptor, 0); + table.addColumn(sailIdColumn, stringMessages.sailNumber()); + table.addColumn(competitorNameColumn, stringMessages.name()); + table.addColumn(raceNameColumn, stringMessages.race()); + table.addColumn(fleetNameColumn, stringMessages.fleet()); + table.addColumn(isHasMatchesColumn, stringMessages.hasMatches()); + + table.addColumnSortHandler(getCompetitorDescriptorTableColumnListSortHandler(competitorNameColumn, sailIdColumn, + raceNameColumn, fleetNameColumn, isHasMatchesColumn)); + } + + private ListHandler getCompetitorDescriptorTableColumnListSortHandler( + TextColumn competitorNameColumn, + Column sailIdColumn, TextColumn raceNameColumn, + TextColumn fleetNameColumn, + TextColumn isHasMatchesColumn) { + ListHandler competitorColumnListHandler = getColumnSortHandler(); + + competitorColumnListHandler.setComparator(competitorNameColumn, new Comparator() { + @Override + public int compare(CompetitorDescriptorDTO cd1, CompetitorDescriptorDTO cd2) { + return cd1.getName().compareTo(cd2.getName()); + } + }); + + competitorColumnListHandler.setComparator(sailIdColumn, new Comparator() { + private final NaturalComparator comparator = new NaturalComparator(/* case sensitive */ false); + + @Override + public int compare(CompetitorDescriptorDTO cd1, CompetitorDescriptorDTO cd2) { + return comparator.compare(cd1.getSailNumber(), cd2.getSailNumber()); + } + }); + + competitorColumnListHandler.setComparator(raceNameColumn, new Comparator() { + private final NaturalComparator comparator = new NaturalComparator(/* case sensitive */ false); + + @Override + public int compare(CompetitorDescriptorDTO cd1, CompetitorDescriptorDTO cd2) { + return comparator.compare(cd1.getRaceName(), cd2.getRaceName()); + } + }); + + competitorColumnListHandler.setComparator(fleetNameColumn, new Comparator() { + private final NaturalComparator comparator = new NaturalComparator(/* case sensitive */ false); + + @Override + public int compare(CompetitorDescriptorDTO cd1, CompetitorDescriptorDTO cd2) { + return comparator.compare(cd1.getFleetName(), cd2.getFleetName()); + } + }); + + competitorColumnListHandler.setComparator(isHasMatchesColumn, new Comparator() { + + @Override + public int compare(CompetitorDescriptorDTO cd1, CompetitorDescriptorDTO cd2) { + Boolean hasMathes1 = competitorImportMatcher.getMatchesCompetitors(cd1).isEmpty(); + Boolean hasMathes2 = competitorImportMatcher.getMatchesCompetitors(cd2).isEmpty(); + return hasMathes1 == hasMathes2 ? 0 : hasMathes1 ? 1 : -1; + } + }); + return competitorColumnListHandler; + } + + public Iterable getAllCompetitorDescriptors() { + return filterablePanelCompetitorDescriptor.getAll(); + } + + public void refreshCompetitorDescriptorList(Iterable competitors) { + filterablePanelCompetitorDescriptor.updateAll(competitors); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java new file mode 100644 index 00000000000..80cc206081a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java @@ -0,0 +1,35 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import com.sap.sailing.gwt.ui.adminconsole.CompetitorImportProviderSelectionDialog.ApplyImportedCompetitorsDialogFactory; + +public class CompetitorImportDialogResult { + private final String providerName; + private final String eventName; + private final String regattaName; + private final ApplyImportedCompetitorsDialogFactory applyImportedCompetitorsDialogFactory; + + public CompetitorImportDialogResult(String providerName, String eventName, String regattaName, + ApplyImportedCompetitorsDialogFactory applyImportedCompetitorsDialogFactory) { + super(); + this.providerName = providerName; + this.eventName = eventName; + this.regattaName = regattaName; + this.applyImportedCompetitorsDialogFactory = applyImportedCompetitorsDialogFactory; + } + + public String getProviderName() { + return providerName; + } + + public String getEventName() { + return eventName; + } + + public String getRegattaName() { + return regattaName; + } + + public ApplyImportedCompetitorsDialogFactory getApplyImportedCompetitorsDialogFactory() { + return applyImportedCompetitorsDialogFactory; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java new file mode 100644 index 00000000000..b485318bcee --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java @@ -0,0 +1,50 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; + +/** + * Using to finding existing competitors which match with imported competitor. + * Currently use the simple exact match comparison. + * @author Alexander_Tatarinovich + * + */ +public class CompetitorImportMatcher { + + private final Iterable existingCompetitorDTOs; + + public CompetitorImportMatcher(Iterable existingCompetitors) { + this.existingCompetitorDTOs = existingCompetitors; + } + + public Set getMatchesCompetitors(CompetitorDescriptorDTO competitorDescriptor) { + Set matchesCompetitor = new HashSet<>(); + if (competitorDescriptor == null) { + return matchesCompetitor; + } + for (CompetitorDTO existingCompetitor : existingCompetitorDTOs) { + if (isEqual(competitorDescriptor, existingCompetitor)) { + matchesCompetitor.add(existingCompetitor); + } + } + return matchesCompetitor; + } + + private boolean isEqual(CompetitorDescriptorDTO competitorDescriptor, CompetitorDTO existingCompetitor) { + return Objects.equals(competitorDescriptor.getName(), existingCompetitor.getName()) + && Objects.equals(competitorDescriptor.getSailNumber(), existingCompetitor.getSailID()) + && compareCountryCode(competitorDescriptor, existingCompetitor); + } + + private boolean compareCountryCode(CompetitorDescriptorDTO competitorDescriptor, CompetitorDTO existingCompetitor) { + return Objects.equals(competitorDescriptor.getCountryName(), existingCompetitor.getCountryName()) + && Objects.equals(competitorDescriptor.getThreeLetterIocCountryCode(), + existingCompetitor.getThreeLetterIocCountryCode()) + && Objects.equals(competitorDescriptor.getTwoLetterIsoCountryCode(), + existingCompetitor.getTwoLetterIsoCountryCode()); + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java new file mode 100644 index 00000000000..3e77594784e --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java @@ -0,0 +1,270 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; +import java.util.Map.Entry; + +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.FocusWidget; +import com.google.gwt.user.client.ui.ListBox; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.domain.base.CompetitorStore; +import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.CompetitorProviderDTO; +import com.sap.sse.common.Util.Pair; +import com.sap.sse.gwt.client.ErrorReporter; +import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator; +import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator; +import com.sap.sse.gwt.client.dialog.DataEntryDialog; +/** + * Define the dialog for displaying competitor providers names and list box of pair "event, regatta" names where we have competitors are available for importing. + * Also defines which dialog would be created for matching and applying result of import using the factory {@link ApplyImportedCompetitorsDialogFactory} + * @author Alexander_Tatarinovich + * + */ +public abstract class CompetitorImportProviderSelectionDialog extends DataEntryDialog { + + private final ListBox competitorListBox; + private final ListBox competitorProviderListBox; + private final BusyIndicator busyIndicator; + + private final SailingServiceAsync sailingService; + private final StringMessages stringMessages; + private final ErrorReporter errorReporter; + + /** + * a unique and human-readable string key for a eventNameRegattaName pair + */ + private final LinkedHashMap> eventRagateNamesByCompetitorListItem; + + public CompetitorImportProviderSelectionDialog(BusynessPanel busynessPanel, + Iterable competitorProviderNames, SailingServiceAsync sailingService, StringMessages stringMessages, + ErrorReporter errorReporter) { + super(stringMessages.importCompetitors(), null, stringMessages.ok(), stringMessages.cancel(), null, + new Callback(sailingService, busynessPanel, errorReporter, stringMessages)); + this.sailingService = sailingService; + this.stringMessages = stringMessages; + this.errorReporter = errorReporter; + + competitorProviderListBox = createListBox(/* isMultipleSelect */ false); + competitorListBox = createListBox(/* isMultipleSelect */ false); + competitorListBox.setVisible(false); + busyIndicator = new SimpleBusyIndicator(); + + eventRagateNamesByCompetitorListItem = new LinkedHashMap<>(); + + competitorProviderListBox.addChangeHandler(new ChangeHandler() { + @Override + public void onChange(ChangeEvent event) { + int selectedIndex = competitorProviderListBox.getSelectedIndex(); + if (selectedIndex > 0) { + String selectedProviderName = competitorProviderListBox.getItemText(selectedIndex); + competitorImportProviderChanged(selectedProviderName); + } else { + competitorImportProviderChanged(null); + } + } + }); + + addProviderNamesToListBox(competitorProviderNames, stringMessages); + } + + private void addProviderNamesToListBox(Iterable competitorProviderNames, StringMessages stringMessages) { + List sortedProviderNames = getSortedProviderNames(competitorProviderNames); + competitorProviderListBox.addItem(stringMessages.selectResultImportProvider()); + for (String providerName : sortedProviderNames) { + competitorProviderListBox.addItem(providerName); + } + } + + private List getSortedProviderNames(Iterable competitorProviderNames) { + List sortedProviderNames = new ArrayList<>(); + for (String providerName : competitorProviderNames) { + sortedProviderNames.add(providerName); + } + Collections.sort(sortedProviderNames); + return sortedProviderNames; + } + + private void competitorImportProviderChanged(String selectedProviderName) { + if (selectedProviderName != null) { + busyIndicator.setBusy(true); + competitorProviderListBox.setEnabled(false); + sailingService.getCompetitorProviderDTOByName(selectedProviderName, + new AsyncCallback() { + @Override + public void onSuccess(CompetitorProviderDTO result) { + updateCompetitorListBox(result); + competitorListBox.setVisible(true); + busyIndicator.setBusy(false); + competitorProviderListBox.setEnabled(true); + } + + @Override + public void onFailure(Throwable caught) { + updateCompetitorListBox(null); + competitorListBox.setVisible(false); + busyIndicator.setBusy(false); + competitorProviderListBox.setEnabled(true); + errorReporter.reportError( + stringMessages.errorLoadingCompetitorImportProviders(caught.getMessage())); + } + }); + } else { + competitorListBox.setVisible(false); + updateCompetitorListBox(null); + } + } + + private void updateCompetitorListBox(CompetitorProviderDTO competitorProvider) { + eventRagateNamesByCompetitorListItem.clear(); + competitorListBox.clear(); + if (competitorProvider != null) { + competitorListBox.addItem(stringMessages.pleaseSelectAScoringResult()); + List> eventAndRegattaNames = getEventAndRegattaNamesWhichHasCompetitors( + competitorProvider); + for (Pair pair : eventAndRegattaNames) { + String eventName = pair.getA(); + String ragattaName = pair.getB(); + String scoreCorrectionName = eventName + ", " + ragattaName; + eventRagateNamesByCompetitorListItem.put(scoreCorrectionName, pair); + competitorListBox.addItem(scoreCorrectionName); + } + } + } + + private List> getEventAndRegattaNamesWhichHasCompetitors( + CompetitorProviderDTO competitorProvider) { + List> eventAndRegattaNames = new ArrayList<>(); + for (Entry> entry : competitorProvider.getHasCompetitorsForRegattasInEvent().entrySet()) { + for (String ragattaName : entry.getValue()) { + eventAndRegattaNames.add(new Pair<>(entry.getKey(), ragattaName)); + } + } + return eventAndRegattaNames; + } + + private static class Callback implements DialogCallback { + private final BusynessPanel busynessPanel; + private final SailingServiceAsync sailingService; + private final ErrorReporter errorReporter; + private final StringMessages stringMessages; + + public Callback(SailingServiceAsync sailingService, BusynessPanel busynessPanel, ErrorReporter errorReporter, + StringMessages stringMessages) { + this.sailingService = sailingService; + this.busynessPanel = busynessPanel; + this.errorReporter = errorReporter; + this.stringMessages = stringMessages; + } + + @Override + public void cancel() { + // don't do anything; dialog was canceled + } + + @Override + public void ok(final CompetitorImportDialogResult competitorImportDialogResult) { + if (competitorImportDialogResult == null) { + return; + } + final String competitorProviderName = competitorImportDialogResult.getProviderName(); + final String eventName = competitorImportDialogResult.getEventName(); + final String regattaName = competitorImportDialogResult.getRegattaName(); + + busynessPanel.setBusy(true); + sailingService.getCompetitorDescriptors(competitorProviderName, eventName, regattaName, + new AsyncCallback>() { + + @Override + public void onFailure(Throwable caught) { + busynessPanel.setBusy(false); + errorReporter.reportError( + stringMessages.errorLoadingCompetitorImportDescriptors(caught.getMessage())); + } + + @Override + public void onSuccess(final Iterable competitorDescriptors) { + sailingService.getCompetitors(new AsyncCallback>() { + @Override + public void onFailure(Throwable caught) { + busynessPanel.setBusy(false); + } + + @Override + public void onSuccess(Iterable competitors) { + busynessPanel.setBusy(false); + final ApplyImportedCompetitorsDialogFactory applyCompetitorDialogFactory = competitorImportDialogResult + .getApplyImportedCompetitorsDialogFactory(); + applyCompetitorDialogFactory + .createApplyImportedCompetitorsDialog(competitorDescriptors, competitors) + .show(); + } + }); + } + }); + } + } + + /** + * Factory for creating specific dialog {@link ApplyImportedCompetitorsDialog} where we will be match and apply imported competitors. + * @param competitorDescriptors imported competitor descriptors {@link CompetitorDescriptorDTO} + * @param competitors existing competitors from {@link CompetitorStore} + * @author Alexander_Tatarinovich + * + */ + protected interface ApplyImportedCompetitorsDialogFactory { + ApplyImportedCompetitorsDialog createApplyImportedCompetitorsDialog( + Iterable competitorDescriptors, Iterable competitors); + } + + /** + * Get factory {@link ApplyImportedCompetitorsDialogFactory} for creating specific dialog {@link ApplyImportedCompetitorsDialog}. + * @return + */ + protected abstract ApplyImportedCompetitorsDialogFactory getApplyImportedCompetitorsDialogFactory(); + + @Override + protected Widget getAdditionalWidget() { + VerticalPanel vPanel = new VerticalPanel(); + vPanel.add(busyIndicator); + vPanel.add(competitorProviderListBox); + vPanel.add(competitorListBox); + return vPanel; + } + + @Override + protected FocusWidget getInitialFocusWidget() { + return competitorProviderListBox; + } + + @Override + protected CompetitorImportDialogResult getResult() { + CompetitorImportDialogResult competitorImportDialogResult = null; + int selectedProviderIndex = competitorProviderListBox.getSelectedIndex(); + if (selectedProviderIndex > 0) { + String selectedProviderName = competitorProviderListBox.getItemText(selectedProviderIndex); + int selectedScoreCorrectionIndex = competitorListBox.getSelectedIndex(); + if (selectedScoreCorrectionIndex > 0) { + Pair pair = eventRagateNamesByCompetitorListItem + .get(competitorListBox.getValue(selectedScoreCorrectionIndex)); + String eventName = pair.getA(); + String regattaName = pair.getB(); + competitorImportDialogResult = new CompetitorImportDialogResult(selectedProviderName, eventName, + regattaName, getApplyImportedCompetitorsDialogFactory()); + } + } + + return competitorImportDialogResult; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java index 6df107211ff..99345cf1a7f 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java @@ -4,6 +4,7 @@ import java.util.Set; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.SimplePanel; @@ -12,10 +13,13 @@ import com.google.gwt.view.client.SelectionChangeEvent; import com.google.gwt.view.client.SelectionChangeEvent.Handler; import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.CompetitorDTOImpl; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sse.gwt.client.ErrorReporter; import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel; +import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator; +import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator; /** * Allows an administrator to view and edit the set of competitors currently maintained by the server. @@ -23,11 +27,13 @@ import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel; * @author Axel Uhl (d043530) * */ -public class CompetitorPanel extends SimplePanel { +public class CompetitorPanel extends SimplePanel implements BusynessPanel{ private final CompetitorTableWrapper> competitorTable; private final RefreshableMultiSelectionModel refreshableCompetitorSelectionModel; private final String leaderboardName; + private final BusyIndicator busyIndicator; + public CompetitorPanel(final SailingServiceAsync sailingService, final StringMessages stringMessages, final ErrorReporter errorReporter) { this(sailingService, null, stringMessages, errorReporter); @@ -39,6 +45,9 @@ public class CompetitorPanel extends SimplePanel { this.leaderboardName = leaderboardName; this.competitorTable = new CompetitorTableWrapper<>(sailingService, stringMessages, errorReporter, /* multiSelection */ true, /* enablePager */ false); this.refreshableCompetitorSelectionModel = (RefreshableMultiSelectionModel) competitorTable.getSelectionModel(); + + busyIndicator = new SimpleBusyIndicator(false, 0.8f); + VerticalPanel mainPanel = new VerticalPanel(); this.setWidget(mainPanel); mainPanel.setWidth("100%"); @@ -85,6 +94,45 @@ public class CompetitorPanel extends SimplePanel { }); buttonPanel.add(selectAllButton); + Button competitorImportButton = new Button(stringMessages.importCompetitors()); + competitorImportButton.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + sailingService.getCompetitorProviderNames(new AsyncCallback>() { + @Override + public void onSuccess(Iterable providerNames) { + + CompetitorImportProviderSelectionDialog dialog = new CompetitorImportProviderSelectionDialog( + CompetitorPanel.this, providerNames, sailingService, stringMessages, errorReporter) { + + @Override + protected ApplyImportedCompetitorsDialogFactory getApplyImportedCompetitorsDialogFactory() { + ApplyImportedCompetitorsDialogFactory matchCompetitorsDialogFactory = new ApplyImportedCompetitorsDialogFactory() { + + @Override + public ApplyImportedCompetitorsDialog createApplyImportedCompetitorsDialog( + final Iterable competitorDescriptors, + final Iterable competitors) { + return new ApplyImportedCompetitorsDialog(competitorDescriptors, + competitors, stringMessages, sailingService, errorReporter); + } + }; + return matchCompetitorsDialogFactory; + } + }; + dialog.show(); + } + + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError( + stringMessages.errorLoadingCompetitorImportProviders(caught.getMessage())); + } + }); + } + }); + buttonPanel.add(competitorImportButton); + //only if this competitor panel is connected to a leaderboard, we want to enable invitations if (leaderboardName != null) { final Button inviteCompetitorsButton = new Button(stringMessages.inviteSelectedCompetitors()); @@ -101,6 +149,7 @@ public class CompetitorPanel extends SimplePanel { } competitorsPanel.add(buttonPanel); + mainPanel.add(busyIndicator); mainPanel.add(competitorTable); refreshableCompetitorSelectionModel.addSelectionChangeHandler(new Handler() { @@ -123,4 +172,11 @@ public class CompetitorPanel extends SimplePanel { public void refreshCompetitorList() { competitorTable.refreshCompetitorList(leaderboardName); } + + @Override + public void setBusy(boolean isBusy) { + if (busyIndicator.isBusy() != isBusy) { + busyIndicator.setBusy(isBusy); + } + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 2d11ab067f7..3e09ac15192 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -32,6 +32,7 @@ import com.sap.sailing.domain.common.abstractlog.NotRevokableException; import com.sap.sailing.domain.common.abstractlog.TimePointSpecificationFoundInLog; import com.sap.sailing.domain.common.dto.BoatDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.IncrementalOrFullLeaderboardDTO; import com.sap.sailing.domain.common.dto.RaceColumnDTO; @@ -52,6 +53,7 @@ import com.sap.sailing.gwt.ui.client.shared.charts.MarkPositionService.MarkTrack import com.sap.sailing.gwt.ui.shared.BulkScoreCorrectionDTO; import com.sap.sailing.gwt.ui.shared.CompactBoatPositionsDTO; import com.sap.sailing.gwt.ui.shared.CompactRaceMapDataDTO; +import com.sap.sailing.gwt.ui.shared.CompetitorProviderDTO; import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.ControlPointDTO; import com.sap.sailing.gwt.ui.shared.CoursePositionsDTO; @@ -342,6 +344,13 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates) throws NoWindException; + Iterable getCompetitorProviderNames(); + + CompetitorProviderDTO getCompetitorProviderDTOByName(String providerName) throws Exception; + + Iterable getCompetitorDescriptors(String competitorProviderName, String eventName, + String regattaName) throws Exception; + WindInfoForRaceDTO getWindSourcesInfo(RegattaAndRaceIdentifier raceIdentifier); ServerInfoDTO getServerInfo(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index 66e3855174a..af70545706d 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -27,6 +27,7 @@ import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.abstractlog.TimePointSpecificationFoundInLog; import com.sap.sailing.domain.common.dto.BoatDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.IncrementalOrFullLeaderboardDTO; import com.sap.sailing.domain.common.dto.RaceColumnDTO; @@ -41,6 +42,7 @@ import com.sap.sailing.gwt.ui.client.shared.charts.MarkPositionService.MarkTrack import com.sap.sailing.gwt.ui.shared.BulkScoreCorrectionDTO; import com.sap.sailing.gwt.ui.shared.CompactBoatPositionsDTO; import com.sap.sailing.gwt.ui.shared.CompactRaceMapDataDTO; +import com.sap.sailing.gwt.ui.shared.CompetitorProviderDTO; import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.ControlPointDTO; import com.sap.sailing.gwt.ui.shared.CoursePositionsDTO; @@ -463,6 +465,13 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan void getScoreCorrections(String scoreCorrectionProviderName, String eventName, String boatClassName, Date timePointWhenResultPublished, AsyncCallback asyncCallback); + void getCompetitorProviderNames(AsyncCallback> callback); + + void getCompetitorProviderDTOByName(String providerName, AsyncCallback callback); + + void getCompetitorDescriptors(String competitorProviderName, String eventName, String regattaName, + AsyncCallback> callback); + void getWindSourcesInfo(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback callback); void getRaceCourse(RegattaAndRaceIdentifier raceIdentifier, Date date, AsyncCallback callback); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index bd587251b9c..8addedb0096 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1741,4 +1741,13 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String externalLinks(); String buoyZoneRadiusInHullLengths(); String incorrectValueForRegattaBuoyZoneRadiusInHullLengths(); + String importCompetitors(); + String choseWhichCompetitorsShouldBeImported(); + String existingCompetitors(); + String importedCompetitors(); + String cannotChoseMoreThenOne(); + String hasMatches(); + String filterImportedCompetitorsByNameSailRaceFleet(); + String errorLoadingCompetitorImportProviders(String message); + String errorLoadingCompetitorImportDescriptors(String message); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 6389f0e472d..8a733c420e1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -1713,3 +1713,12 @@ filterDeviceMappings=Filter device mappings raceStartAnalysis=Race Start Analysis buoyZoneRadiusInHullLengths=Buoy zone radius in hull lengths (e.g., 2 or 3) incorrectValueForRegattaBuoyZoneRadiusInHullLengths=Incorrect value for the buoy zone radius in hull lengths +importCompetitors=Import Competitors +choseWhichCompetitorsShouldBeImported=Chose which competitors should be imported +existingCompetitors=Existing Competitors +importedCompetitors=Imported Competitors +cannotChoseMoreThenOne=Cannot chose more then one. +hasMatches=Has matches +filterImportedCompetitorsByNameSailRaceFleet=Filter imported competitors by name, sail number, race or fleet +errorLoadingCompetitorImportProviders=Error loading competitor import providers: {0} +errorLoadingCompetitorImportDescriptors=Error loading competitor import descriptors: {0} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index cdcc7d02788..ebd7a3e32b9 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -55,6 +55,8 @@ import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; +import com.sap.sailing.competitorimport.CompetitorDescriptor; +import com.sap.sailing.competitorimport.CompetitorProvider; import com.sap.sailing.domain.abstractlog.AbstractLog; import com.sap.sailing.domain.abstractlog.AbstractLogEvent; import com.sap.sailing.domain.abstractlog.impl.AllEventsOfTypeFinder; @@ -106,6 +108,7 @@ import com.sap.sailing.domain.base.LeaderboardGroupBase; import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Nationality; +import com.sap.sailing.domain.base.Person; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.RaceColumnInSeries; import com.sap.sailing.domain.base.RaceDefinition; @@ -182,11 +185,13 @@ import com.sap.sailing.domain.common.abstractlog.TimePointSpecificationFoundInLo import com.sap.sailing.domain.common.dto.BoatClassDTO; import com.sap.sailing.domain.common.dto.BoatDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.FullLeaderboardDTO; import com.sap.sailing.domain.common.dto.IncrementalLeaderboardDTO; import com.sap.sailing.domain.common.dto.IncrementalOrFullLeaderboardDTO; import com.sap.sailing.domain.common.dto.LeaderboardDTO; +import com.sap.sailing.domain.common.dto.PersonDTO; import com.sap.sailing.domain.common.dto.RaceColumnDTO; import com.sap.sailing.domain.common.dto.RaceColumnDTOFactory; import com.sap.sailing.domain.common.dto.RaceColumnInSeriesDTO; @@ -301,6 +306,7 @@ import com.sap.sailing.gwt.ui.client.shared.charts.MarkPositionService.MarkTrack import com.sap.sailing.gwt.ui.shared.BulkScoreCorrectionDTO; import com.sap.sailing.gwt.ui.shared.CompactBoatPositionsDTO; import com.sap.sailing.gwt.ui.shared.CompactRaceMapDataDTO; +import com.sap.sailing.gwt.ui.shared.CompetitorProviderDTO; import com.sap.sailing.gwt.ui.shared.CompetitorRaceDataDTO; import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.ControlPointDTO; @@ -505,6 +511,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S private final ServiceTracker scoreCorrectionProviderServiceTracker; + private final ServiceTracker competitorProviderServiceTracker; + private final MongoObjectFactory mongoObjectFactory; private final SwissTimingAdapterPersistence swissTimingAdapterPersistence; @@ -581,6 +589,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S /* raceLogResolver */ getService()); scoreCorrectionProviderServiceTracker = ServiceTrackerFactory.createAndOpen(context, ScoreCorrectionProvider.class); + competitorProviderServiceTracker = ServiceTrackerFactory.createAndOpen(context, CompetitorProvider.class); tractracDomainObjectFactory = com.sap.sailing.domain.tractracadapter.persistence.PersistenceFactory.INSTANCE .createDomainObjectFactory(mongoObjectFactory.getDatabase(), getTracTracAdapter() .getTracTracDomainFactory()); @@ -681,6 +690,96 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S return new ScoreCorrectionProviderDTO(scoreCorrectionProvider.getName(), hasResultsForBoatClassFromDateByEventName); } + @Override + public Iterable getCompetitorProviderNames() { + List result = new ArrayList(); + for (CompetitorProvider competitorProvider : getAllCompetotorProviders()) { + result.add(competitorProvider.getName()); + } + return result; + } + + private Iterable getAllCompetotorProviders() { + final Object[] services = competitorProviderServiceTracker.getServices(); + List result = new ArrayList(); + if (services != null) { + for (Object service : services) { + result.add((CompetitorProvider) service); + } + } + return result; + } + + @Override + public CompetitorProviderDTO getCompetitorProviderDTOByName(String providerName) throws Exception { + CompetitorProviderDTO result = null; + for (CompetitorProvider competitorProvider : getAllCompetotorProviders()) { + if (competitorProvider.getName().equals(providerName)) { + result = convertToCompetitorProviderDTO(competitorProvider); + break; + } + } + return result; + } + + private CompetitorProviderDTO convertToCompetitorProviderDTO(CompetitorProvider competitorProvider) + throws Exception { + Map> hasResultsForRegattaByEventName = new HashMap>(); + for (Map.Entry> entry : competitorProvider + .getHasCompetitorsForRegattasInEvent().entrySet()) { + Set regattas = new HashSet<>(entry.getValue()); + hasResultsForRegattaByEventName.put(entry.getKey(), regattas); + } + return new CompetitorProviderDTO(competitorProvider.getName(), hasResultsForRegattaByEventName); + } + + @Override + public Iterable getCompetitorDescriptors(String competitorProviderName, String eventName, + String regattaName) throws Exception { + for (CompetitorProvider cp : getAllCompetotorProviders()) { + if (cp.getName().equals(competitorProviderName)) { + Iterable competitorDescriptors = cp.getCompetitorDescriptors(eventName, regattaName); + Set competitorDescriptorDTOs = getCompetitorProviderDTOs(competitorDescriptors); + return competitorDescriptorDTOs; + } + } + return Collections.emptySet(); + } + + private Set getCompetitorProviderDTOs( + Iterable competitorDescriptors) { + Set competitorDescriptorDTOs = new HashSet<>(); + for (CompetitorDescriptor cd : competitorDescriptors) { + CompetitorDescriptorDTO cdDTO = convertToCompetitorDescriptorDTO(cd); + competitorDescriptorDTOs.add(cdDTO); + } + return competitorDescriptorDTOs; + } + + private CompetitorDescriptorDTO convertToCompetitorDescriptorDTO(CompetitorDescriptor competitorDescriptor) { + Set persons = new HashSet<>(); + for (Person person : competitorDescriptor.getPersons()) { + String nationalityThreeLetterIOCAcronym = person.getNationality() != null + ? person.getNationality().getThreeLetterIOCAcronym() : null; + PersonDTO personDTO = new PersonDTO(person.getName(), person.getDateOfBirth(), person.getDescription(), + nationalityThreeLetterIOCAcronym); + persons.add(personDTO); + } + + CountryCode countryCode = competitorDescriptor.getCountryCode(); + String countryName = countryCode == null ? null : countryCode.getName(); + String twoLetterIsoCountryCode = countryCode == null ? null : countryCode.getTwoLetterISOCode(); + String threeLetterIocCountryCode = countryCode == null ? null : countryCode.getThreeLetterIOCCode(); + + CompetitorDescriptorDTO competitorDescriptorDTO = new CompetitorDescriptorDTO( + competitorDescriptor.getEventName(), competitorDescriptor.getRegattaName(), + competitorDescriptor.getRaceName(), competitorDescriptor.getFleetName(), + competitorDescriptor.getSailNumber(), competitorDescriptor.getCompetitorName(), countryName, + twoLetterIsoCountryCode, threeLetterIocCountryCode, persons); + + return competitorDescriptorDTO; + } + /** * If date is null, the {@link LiveLeaderboardUpdater} for the * leaderboardName requested is obtained or created if it doesn't exist yet. The request is then passed diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java new file mode 100644 index 00000000000..6fdae84410a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java @@ -0,0 +1,46 @@ +package com.sap.sailing.gwt.ui.shared; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import com.sap.sailing.domain.common.dto.NamedDTO; + +public class CompetitorProviderDTO extends NamedDTO { + private static final long serialVersionUID = -8911619278385485713L; + + private Map> hasCompetitorsForRegattasInEvent; + + public CompetitorProviderDTO() { + } + + public CompetitorProviderDTO(String name, Map> hasCompetitorsForRegattasInEvent) { + super(name); + this.hasCompetitorsForRegattasInEvent = hasCompetitorsForRegattasInEvent; + } + + public Map> getHasCompetitorsForRegattasInEvent() { + return hasCompetitorsForRegattasInEvent; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Objects.hash(hasCompetitorsForRegattasInEvent); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + CompetitorProviderDTO other = (CompetitorProviderDTO) obj; + return Objects.equals(hasCompetitorsForRegattasInEvent, other.hasCompetitorsForRegattasInEvent); + } + +} diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Activator.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Activator.java index 1e810ca0f65..fcc37139458 100755 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Activator.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/Activator.java @@ -13,6 +13,7 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; +import com.sap.sailing.competitorimport.CompetitorProvider; import com.sap.sailing.domain.common.ScoreCorrectionProvider; import com.sap.sailing.resultimport.ResultUrlRegistry; import com.sap.sailing.resultimport.impl.ResultUrlRegistryServiceTrackerCustomizer; @@ -33,6 +34,13 @@ public class Activator implements BundleActivator { ParserFactory.INSTANCE, resultUrlRegistry); return service; } + + @Override + protected CompetitorProvider configureCompetitorProvider(ResultUrlRegistry resultUrlRegistry) { + final CompetitorProvider service = new CompetitorImporter(ParserFactory.INSTANCE, + resultUrlRegistry); + return service; + } }); resultUrlRegistryServiceTracker.open(); diff --git a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java index c32614a1cae..b6b27d180a1 100644 --- a/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java +++ b/java/com.sap.sailing.manage2sail.resultimport/src/com/sap/sailing/manage2sail/resultimport/CompetitorImporter.java @@ -54,6 +54,11 @@ public class CompetitorImporter extends AbstractManage2SailProvider implements C return result; } + @Override + public String getName() { + return NAME; + } + @Override public Iterable getCompetitorDescriptors(String eventName, String regattaName) throws JAXBException, IOException { final List result = new ArrayList<>(); diff --git a/java/com.sap.sailing.resultimport/META-INF/MANIFEST.MF b/java/com.sap.sailing.resultimport/META-INF/MANIFEST.MF index 442f3f929e3..639dda079ba 100644 --- a/java/com.sap.sailing.resultimport/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.resultimport/META-INF/MANIFEST.MF @@ -9,7 +9,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: com.sap.sailing.resultimport, com.sap.sailing.resultimport.impl -Import-Package: com.sap.sailing.domain.base.impl, +Import-Package: com.sap.sailing.competitorimport, + com.sap.sailing.domain.base.impl, com.sap.sailing.domain.common, com.sap.sailing.domain.common.impl, com.sap.sailing.domain.persistence, diff --git a/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java b/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java index 48db17c3005..7fb6ae30082 100644 --- a/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java +++ b/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java @@ -4,6 +4,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTrackerCustomizer; +import com.sap.sailing.competitorimport.CompetitorProvider; import com.sap.sailing.domain.common.ScoreCorrectionProvider; import com.sap.sailing.resultimport.ResultUrlRegistry; @@ -24,11 +25,24 @@ public abstract class ResultUrlRegistryServiceTrackerCustomizer implements ScoreCorrectionProvider scoreCorrectionProvider = configureScoreCorrectionProvider(resultUrlRegistry); bundleContext.registerService(ScoreCorrectionProvider.class, scoreCorrectionProvider, /* properties */null); + + registerCompetitorImportService(resultUrlRegistry); return resultUrlRegistry; } + private void registerCompetitorImportService(ResultUrlRegistry resultUrlRegistry) { + CompetitorProvider competitorProvider = configureCompetitorProvider(resultUrlRegistry); + if (competitorProvider != null) { + bundleContext.registerService(CompetitorProvider.class, competitorProvider, /* properties */null); + } + } + protected abstract ScoreCorrectionProvider configureScoreCorrectionProvider(ResultUrlRegistry resultUrlRegistry); + protected CompetitorProvider configureCompetitorProvider(ResultUrlRegistry resultUrlRegistry) { + return null; + } + @Override public void modifiedService(ServiceReference reference, ResultUrlRegistry service) { } From 473d3647a00925176574642e622e0bc20b7dda48 Mon Sep 17 00:00:00 2001 From: Alexander Tatarinovich Date: Tue, 15 Nov 2016 12:04:53 +0300 Subject: [PATCH 012/214] bug 3246: add competitor import bundle to all launch config Change-Id: Iea68d9fae2b327a5bb42d1e7166376258e43d3c3 --- java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch | 2 +- java/com.sap.sailing.server/SailingServer (No Proxy).launch | 2 +- .../SailingServer (No Proxy, Cached MTB).launch | 2 +- .../SailingServer (No Proxy, Jetty on 8889).launch | 2 +- .../SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch | 2 +- ...gServer (No Proxy, Jetty on 8889, auto-replicate dev).launch | 2 +- ...ilingServer (No Proxy, Jetty on 8889, auto-replicate).launch | 2 +- .../SailingServer (No Proxy, Jetty on 8890).launch | 2 +- .../SailingServer (No Proxy, Remote Debug SAP VM).launch | 2 +- .../SailingServer (No Proxy, winddbTest).launch | 2 +- java/com.sap.sailing.server/SailingServer (Proxy).launch | 2 +- .../SailingServer (Proxy, Jetty on 8889).launch | 2 +- .../SailingServer (Proxy, Remote Debug SAP VM).launch | 2 +- .../SailingServer (Proxy, SwissTiming Live Simulation).launch | 2 +- .../SailingServer (Proxy, winddbTest).launch | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch index 370c226f7c8..d35fdacb154 100644 --- a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch @@ -34,5 +34,5 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy).launch b/java/com.sap.sailing.server/SailingServer (No Proxy).launch index 609a178b807..1125ca4e916 100644 --- a/java/com.sap.sailing.server/SailingServer (No Proxy).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy).launch @@ -34,5 +34,5 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch index da6f82394e2..1a689b7a036 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch @@ -33,5 +33,5 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch index 07154bbdc1c..b19d7baa5e9 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch @@ -27,6 +27,6 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch index 84f60f4a366..5c716ce09e0 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch @@ -27,6 +27,6 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch index cc3000cf396..bd1889d7d39 100644 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch @@ -27,6 +27,6 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch index 71b2a9a98dd..a7aeced8ee4 100644 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch @@ -29,6 +29,6 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch index 699eeb905d7..3e92bc7d56c 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch @@ -27,6 +27,6 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch index c95cc38ef1b..37f3b94f90a 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch @@ -27,5 +27,5 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch index b6c098e649f..43ccab2b059 100755 --- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch @@ -33,5 +33,5 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (Proxy).launch b/java/com.sap.sailing.server/SailingServer (Proxy).launch index f14bce336b7..fd55d670afd 100755 --- a/java/com.sap.sailing.server/SailingServer (Proxy).launch +++ b/java/com.sap.sailing.server/SailingServer (Proxy).launch @@ -36,6 +36,6 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch index eb8118e3cc1..a6652d34410 100755 --- a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch +++ b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch @@ -27,6 +27,6 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch index c902bdcac5c..490d5c3fc13 100755 --- a/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch +++ b/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch @@ -27,5 +27,5 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch b/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch index db198049d93..1c6c2148484 100755 --- a/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch +++ b/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch @@ -26,5 +26,5 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch index c9d818214b7..b9d676d914e 100755 --- a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch +++ b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch @@ -28,6 +28,6 @@ - + From dbc38da8e4a79d80441b916011a7c13dcb633d20 Mon Sep 17 00:00:00 2001 From: Alexander Tatarinovich Date: Tue, 15 Nov 2016 13:02:07 +0300 Subject: [PATCH 013/214] bug3246: some refactoring fixes Change-Id: I32389625c7a8febfcefbb7ee2499cc0399348a08 --- .../common/dto/CompetitorDescriptorDTO.java | 9 ++- .../sailing/domain/common/dto/PersonDTO.java | 10 +-- .../ApplyImportedCompetitorsDialog.java | 2 +- .../{BusynessPanel.java => Busyness.java} | 4 +- .../CompetitorDescriptorTableWrapper.java | 4 +- .../CompetitorImportDialogResult.java | 35 ----------- .../adminconsole/CompetitorImportMatcher.java | 2 +- ...mpetitorImportProviderSelectionDialog.java | 62 ++++++++++--------- ...CompetitorImportSelectionDialogResult.java | 25 ++++++++ .../gwt/ui/adminconsole/CompetitorPanel.java | 42 +++++++------ .../sailing/gwt/ui/client/StringMessages.java | 3 +- .../gwt/ui/client/StringMessages.properties | 3 +- .../gwt/ui/server/SailingServiceImpl.java | 23 ++----- .../gwt/ui/shared/CompetitorProviderDTO.java | 9 ++- ...ltUrlRegistryServiceTrackerCustomizer.java | 2 + 15 files changed, 113 insertions(+), 122 deletions(-) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/{BusynessPanel.java => Busyness.java} (52%) delete mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportSelectionDialogResult.java diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java index 6a9e77e8b9b..efcac1ca42b 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDescriptorDTO.java @@ -118,12 +118,15 @@ public class CompetitorDescriptorDTO extends NamedDTO { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (!super.equals(obj)) + } + if (getClass() != obj.getClass()) { return false; - if (getClass() != obj.getClass()) + } + if (!super.equals(obj)) { return false; + } CompetitorDescriptorDTO other = (CompetitorDescriptorDTO) obj; return Objects.equals(countryName, other.countryName) && Objects.equals(eventName, other.eventName) && Objects.equals(fleetName, other.fleetName) && Objects.deepEquals(persons, other.persons) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java index ffe19c6c193..3a002cbf40d 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/PersonDTO.java @@ -53,13 +53,15 @@ public class PersonDTO extends NamedDTO { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (!super.equals(obj)) + } + if (getClass() != obj.getClass()) { return false; - if (getClass() != obj.getClass()) + } + if (!super.equals(obj)) { return false; - + } PersonDTO other = (PersonDTO) obj; return Objects.equals(dateOfBirth, other.dateOfBirth) && Objects.equals(description, other.description) && Objects.equals(nationalityThreeLetterIOCAcronym, other.nationalityThreeLetterIOCAcronym); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java index 9d3917f5286..12d397e8da6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java @@ -46,7 +46,7 @@ public class ApplyImportedCompetitorsDialog extends DataEntryDialog competitorDescriptorDTOs, final Iterable existingCompetitor, StringMessages stringMessages, SailingServiceAsync sailingService, ErrorReporter errorReporter) { - super(stringMessages.importCompetitors(), stringMessages.choseWhichCompetitorsShouldBeImported(), + super(stringMessages.importCompetitors(), stringMessages.chooseWhichCompetitorsShouldBeImported(), stringMessages.ok(), stringMessages.cancel(), null, /* TODO: implement calback */null); this.stringMessages = stringMessages; this.sailingService = sailingService; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/BusynessPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/Busyness.java similarity index 52% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/BusynessPanel.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/Busyness.java index 0023b14ab0d..cf58ad47325 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/BusynessPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/Busyness.java @@ -1,10 +1,10 @@ package com.sap.sailing.gwt.ui.adminconsole; /** - * Declare that panel can be busy when some actions are performed. + * Declare that we can change the busy state when some actions are performed. * * @author Alexander_Tatarinovich */ -public interface BusynessPanel { +public interface Busyness { void setBusy(boolean isBusy); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java index 1651d8eb4b0..95d6c69be98 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorDescriptorTableWrapper.java @@ -141,9 +141,11 @@ public class CompetitorDescriptorTableWrapper competitorColumnListHandler = getColumnSortHandler(); competitorColumnListHandler.setComparator(competitorNameColumn, new Comparator() { + private final NaturalComparator comparator = new NaturalComparator(/* case sensitive */ false); + @Override public int compare(CompetitorDescriptorDTO cd1, CompetitorDescriptorDTO cd2) { - return cd1.getName().compareTo(cd2.getName()); + return comparator.compare(cd1.getName(), cd2.getName()); } }); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java deleted file mode 100644 index 80cc206081a..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportDialogResult.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sap.sailing.gwt.ui.adminconsole; - -import com.sap.sailing.gwt.ui.adminconsole.CompetitorImportProviderSelectionDialog.ApplyImportedCompetitorsDialogFactory; - -public class CompetitorImportDialogResult { - private final String providerName; - private final String eventName; - private final String regattaName; - private final ApplyImportedCompetitorsDialogFactory applyImportedCompetitorsDialogFactory; - - public CompetitorImportDialogResult(String providerName, String eventName, String regattaName, - ApplyImportedCompetitorsDialogFactory applyImportedCompetitorsDialogFactory) { - super(); - this.providerName = providerName; - this.eventName = eventName; - this.regattaName = regattaName; - this.applyImportedCompetitorsDialogFactory = applyImportedCompetitorsDialogFactory; - } - - public String getProviderName() { - return providerName; - } - - public String getEventName() { - return eventName; - } - - public String getRegattaName() { - return regattaName; - } - - public ApplyImportedCompetitorsDialogFactory getApplyImportedCompetitorsDialogFactory() { - return applyImportedCompetitorsDialogFactory; - } -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java index b485318bcee..67b87728690 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportMatcher.java @@ -14,7 +14,7 @@ import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; * */ public class CompetitorImportMatcher { - + //FIXME: Not sure about the amount of data. May be need to implement some cache for that. private final Iterable existingCompetitorDTOs; public CompetitorImportMatcher(Iterable existingCompetitors) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java index 3e77594784e..13822ecbfe3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java @@ -25,13 +25,16 @@ import com.sap.sse.gwt.client.ErrorReporter; import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator; import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator; import com.sap.sse.gwt.client.dialog.DataEntryDialog; + /** - * Define the dialog for displaying competitor providers names and list box of pair "event, regatta" names where we have competitors are available for importing. - * Also defines which dialog would be created for matching and applying result of import using the factory {@link ApplyImportedCompetitorsDialogFactory} + * Defines the dialog for displaying competitor provider names and list box of pair "event, regatta" names where we have + * competitors are available for importing. Also defines which dialog would be created for matching and applying result + * of import using the factory {@link ApplyImportedCompetitorsDialogFactory} + * * @author Alexander_Tatarinovich * */ -public abstract class CompetitorImportProviderSelectionDialog extends DataEntryDialog { +public class CompetitorImportProviderSelectionDialog extends DataEntryDialog { private final ListBox competitorListBox; private final ListBox competitorProviderListBox; @@ -46,11 +49,12 @@ public abstract class CompetitorImportProviderSelectionDialog extends DataEntryD */ private final LinkedHashMap> eventRagateNamesByCompetitorListItem; - public CompetitorImportProviderSelectionDialog(BusynessPanel busynessPanel, - Iterable competitorProviderNames, SailingServiceAsync sailingService, StringMessages stringMessages, - ErrorReporter errorReporter) { + public CompetitorImportProviderSelectionDialog(ApplyImportedCompetitorsDialogFactory applyCompetitorsDialogFactory, + Busyness busynessPanel, Iterable competitorProviderNames, SailingServiceAsync sailingService, + StringMessages stringMessages, ErrorReporter errorReporter) { super(stringMessages.importCompetitors(), null, stringMessages.ok(), stringMessages.cancel(), null, - new Callback(sailingService, busynessPanel, errorReporter, stringMessages)); + new Callback(applyCompetitorsDialogFactory, sailingService, busynessPanel, errorReporter, + stringMessages)); this.sailingService = sailingService; this.stringMessages = stringMessages; this.errorReporter = errorReporter; @@ -153,18 +157,21 @@ public abstract class CompetitorImportProviderSelectionDialog extends DataEntryD return eventAndRegattaNames; } - private static class Callback implements DialogCallback { - private final BusynessPanel busynessPanel; + private static class Callback implements DialogCallback { + private final Busyness busynessPanel; private final SailingServiceAsync sailingService; private final ErrorReporter errorReporter; private final StringMessages stringMessages; + private final ApplyImportedCompetitorsDialogFactory applyCompetitorsDialogFactory; - public Callback(SailingServiceAsync sailingService, BusynessPanel busynessPanel, ErrorReporter errorReporter, + public Callback(ApplyImportedCompetitorsDialogFactory applyCompetitorsDialogFactory, + SailingServiceAsync sailingService, Busyness busynessPanel, ErrorReporter errorReporter, StringMessages stringMessages) { this.sailingService = sailingService; this.busynessPanel = busynessPanel; this.errorReporter = errorReporter; this.stringMessages = stringMessages; + this.applyCompetitorsDialogFactory = applyCompetitorsDialogFactory; } @Override @@ -173,7 +180,7 @@ public abstract class CompetitorImportProviderSelectionDialog extends DataEntryD } @Override - public void ok(final CompetitorImportDialogResult competitorImportDialogResult) { + public void ok(final CompetitorImportSelectionDialogResult competitorImportDialogResult) { if (competitorImportDialogResult == null) { return; } @@ -203,9 +210,8 @@ public abstract class CompetitorImportProviderSelectionDialog extends DataEntryD @Override public void onSuccess(Iterable competitors) { busynessPanel.setBusy(false); - final ApplyImportedCompetitorsDialogFactory applyCompetitorDialogFactory = competitorImportDialogResult - .getApplyImportedCompetitorsDialogFactory(); - applyCompetitorDialogFactory + + applyCompetitorsDialogFactory .createApplyImportedCompetitorsDialog(competitorDescriptors, competitors) .show(); } @@ -216,23 +222,21 @@ public abstract class CompetitorImportProviderSelectionDialog extends DataEntryD } /** - * Factory for creating specific dialog {@link ApplyImportedCompetitorsDialog} where we will be match and apply imported competitors. - * @param competitorDescriptors imported competitor descriptors {@link CompetitorDescriptorDTO} - * @param competitors existing competitors from {@link CompetitorStore} + * Factory for creating specific dialog {@link ApplyImportedCompetitorsDialog} where we will be match and apply + * imported competitors. + * + * @param competitorDescriptors + * imported competitor descriptors {@link CompetitorDescriptorDTO} + * @param competitors + * existing competitors from {@link CompetitorStore} * @author Alexander_Tatarinovich * */ - protected interface ApplyImportedCompetitorsDialogFactory { + public interface ApplyImportedCompetitorsDialogFactory { ApplyImportedCompetitorsDialog createApplyImportedCompetitorsDialog( Iterable competitorDescriptors, Iterable competitors); } - /** - * Get factory {@link ApplyImportedCompetitorsDialogFactory} for creating specific dialog {@link ApplyImportedCompetitorsDialog}. - * @return - */ - protected abstract ApplyImportedCompetitorsDialogFactory getApplyImportedCompetitorsDialogFactory(); - @Override protected Widget getAdditionalWidget() { VerticalPanel vPanel = new VerticalPanel(); @@ -248,8 +252,8 @@ public abstract class CompetitorImportProviderSelectionDialog extends DataEntryD } @Override - protected CompetitorImportDialogResult getResult() { - CompetitorImportDialogResult competitorImportDialogResult = null; + protected CompetitorImportSelectionDialogResult getResult() { + CompetitorImportSelectionDialogResult competitorImportDialogResult = null; int selectedProviderIndex = competitorProviderListBox.getSelectedIndex(); if (selectedProviderIndex > 0) { String selectedProviderName = competitorProviderListBox.getItemText(selectedProviderIndex); @@ -259,12 +263,10 @@ public abstract class CompetitorImportProviderSelectionDialog extends DataEntryD .get(competitorListBox.getValue(selectedScoreCorrectionIndex)); String eventName = pair.getA(); String regattaName = pair.getB(); - competitorImportDialogResult = new CompetitorImportDialogResult(selectedProviderName, eventName, - regattaName, getApplyImportedCompetitorsDialogFactory()); + competitorImportDialogResult = new CompetitorImportSelectionDialogResult(selectedProviderName, + eventName, regattaName); } } - return competitorImportDialogResult; } - } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportSelectionDialogResult.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportSelectionDialogResult.java new file mode 100644 index 00000000000..771e4dede89 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportSelectionDialogResult.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +public class CompetitorImportSelectionDialogResult { + private final String providerName; + private final String eventName; + private final String regattaName; + + public CompetitorImportSelectionDialogResult(String providerName, String eventName, String regattaName) { + this.providerName = providerName; + this.eventName = eventName; + this.regattaName = regattaName; + } + + public String getProviderName() { + return providerName; + } + + public String getEventName() { + return eventName; + } + + public String getRegattaName() { + return regattaName; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java index 99345cf1a7f..e9f98d83ea2 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java @@ -14,6 +14,7 @@ import com.google.gwt.view.client.SelectionChangeEvent.Handler; import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.CompetitorDTOImpl; import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; +import com.sap.sailing.gwt.ui.adminconsole.CompetitorImportProviderSelectionDialog.ApplyImportedCompetitorsDialogFactory; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sse.gwt.client.ErrorReporter; @@ -27,7 +28,7 @@ import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator; * @author Axel Uhl (d043530) * */ -public class CompetitorPanel extends SimplePanel implements BusynessPanel{ +public class CompetitorPanel extends SimplePanel implements Busyness{ private final CompetitorTableWrapper> competitorTable; private final RefreshableMultiSelectionModel refreshableCompetitorSelectionModel; private final String leaderboardName; @@ -101,32 +102,19 @@ public class CompetitorPanel extends SimplePanel implements BusynessPanel{ sailingService.getCompetitorProviderNames(new AsyncCallback>() { @Override public void onSuccess(Iterable providerNames) { + ApplyImportedCompetitorsDialogFactory applyCompetitorsDialogFactory = getApplyCompetitorsDialogFactory( + sailingService, stringMessages, errorReporter); CompetitorImportProviderSelectionDialog dialog = new CompetitorImportProviderSelectionDialog( - CompetitorPanel.this, providerNames, sailingService, stringMessages, errorReporter) { - - @Override - protected ApplyImportedCompetitorsDialogFactory getApplyImportedCompetitorsDialogFactory() { - ApplyImportedCompetitorsDialogFactory matchCompetitorsDialogFactory = new ApplyImportedCompetitorsDialogFactory() { - - @Override - public ApplyImportedCompetitorsDialog createApplyImportedCompetitorsDialog( - final Iterable competitorDescriptors, - final Iterable competitors) { - return new ApplyImportedCompetitorsDialog(competitorDescriptors, - competitors, stringMessages, sailingService, errorReporter); - } - }; - return matchCompetitorsDialogFactory; - } - }; + applyCompetitorsDialogFactory, CompetitorPanel.this, providerNames, sailingService, + stringMessages, errorReporter); dialog.show(); } @Override public void onFailure(Throwable caught) { - errorReporter.reportError( - stringMessages.errorLoadingCompetitorImportProviders(caught.getMessage())); + errorReporter + .reportError(stringMessages.errorLoadingCompetitorImportProviders(caught.getMessage())); } }); } @@ -165,6 +153,20 @@ public class CompetitorPanel extends SimplePanel implements BusynessPanel{ } } + private ApplyImportedCompetitorsDialogFactory getApplyCompetitorsDialogFactory( + final SailingServiceAsync sailingService, final StringMessages stringMessages, + final ErrorReporter errorReporter) { + return new ApplyImportedCompetitorsDialogFactory() { + @Override + public ApplyImportedCompetitorsDialog createApplyImportedCompetitorsDialog( + final Iterable competitorDescriptors, + final Iterable competitors) { + return new ApplyImportedCompetitorsDialog(competitorDescriptors, competitors, stringMessages, + sailingService, errorReporter); + } + }; + } + private void openAddCompetitorDialog() { competitorTable.openEditCompetitorDialog(new CompetitorDTOImpl(), /* boat class to be used from CompetitorDTO */ null); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 8addedb0096..d6ab7fc83f8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1742,10 +1742,9 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String buoyZoneRadiusInHullLengths(); String incorrectValueForRegattaBuoyZoneRadiusInHullLengths(); String importCompetitors(); - String choseWhichCompetitorsShouldBeImported(); + String chooseWhichCompetitorsShouldBeImported(); String existingCompetitors(); String importedCompetitors(); - String cannotChoseMoreThenOne(); String hasMatches(); String filterImportedCompetitorsByNameSailRaceFleet(); String errorLoadingCompetitorImportProviders(String message); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 8a733c420e1..19c2b8b7aad 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -1714,10 +1714,9 @@ raceStartAnalysis=Race Start Analysis buoyZoneRadiusInHullLengths=Buoy zone radius in hull lengths (e.g., 2 or 3) incorrectValueForRegattaBuoyZoneRadiusInHullLengths=Incorrect value for the buoy zone radius in hull lengths importCompetitors=Import Competitors -choseWhichCompetitorsShouldBeImported=Chose which competitors should be imported +chooseWhichCompetitorsShouldBeImported=Choose which competitors should be imported existingCompetitors=Existing Competitors importedCompetitors=Imported Competitors -cannotChoseMoreThenOne=Cannot chose more then one. hasMatches=Has matches filterImportedCompetitorsByNameSailRaceFleet=Filter imported competitors by name, sail number, race or fleet errorLoadingCompetitorImportProviders=Error loading competitor import providers: {0} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index ebd7a3e32b9..81a0e7031c1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -692,7 +692,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public Iterable getCompetitorProviderNames() { - List result = new ArrayList(); + List result = new ArrayList<>(); for (CompetitorProvider competitorProvider : getAllCompetotorProviders()) { result.add(competitorProvider.getName()); } @@ -701,7 +701,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S private Iterable getAllCompetotorProviders() { final Object[] services = competitorProviderServiceTracker.getServices(); - List result = new ArrayList(); + List result = new ArrayList<>(); if (services != null) { for (Object service : services) { result.add((CompetitorProvider) service); @@ -712,25 +712,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public CompetitorProviderDTO getCompetitorProviderDTOByName(String providerName) throws Exception { - CompetitorProviderDTO result = null; for (CompetitorProvider competitorProvider : getAllCompetotorProviders()) { if (competitorProvider.getName().equals(providerName)) { - result = convertToCompetitorProviderDTO(competitorProvider); - break; + return new CompetitorProviderDTO(competitorProvider.getName(), + new HashMap<>(competitorProvider.getHasCompetitorsForRegattasInEvent())); } } - return result; - } - - private CompetitorProviderDTO convertToCompetitorProviderDTO(CompetitorProvider competitorProvider) - throws Exception { - Map> hasResultsForRegattaByEventName = new HashMap>(); - for (Map.Entry> entry : competitorProvider - .getHasCompetitorsForRegattasInEvent().entrySet()) { - Set regattas = new HashSet<>(entry.getValue()); - hasResultsForRegattaByEventName.put(entry.getKey(), regattas); - } - return new CompetitorProviderDTO(competitorProvider.getName(), hasResultsForRegattaByEventName); + return null; } @Override @@ -1573,7 +1561,6 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S polarDiagram = new PolarDiagramGPS(boatClass, polarData); } catch (SparseSimulationDataException e) { polarDiagram = null; - // TODO: raise a UI message, to inform user about missing polar data resulting in unability to simulate } result = polarDiagram != null; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java index 6fdae84410a..537854dd2e0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/CompetitorProviderDTO.java @@ -33,12 +33,15 @@ public class CompetitorProviderDTO extends NamedDTO { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (!super.equals(obj)) + } + if (getClass() != obj.getClass()) { return false; - if (getClass() != obj.getClass()) + } + if (!super.equals(obj)) { return false; + } CompetitorProviderDTO other = (CompetitorProviderDTO) obj; return Objects.equals(hasCompetitorsForRegattasInEvent, other.hasCompetitorsForRegattasInEvent); } diff --git a/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java b/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java index 7fb6ae30082..83d7fc28efb 100644 --- a/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java +++ b/java/com.sap.sailing.resultimport/src/com/sap/sailing/resultimport/impl/ResultUrlRegistryServiceTrackerCustomizer.java @@ -39,6 +39,8 @@ public abstract class ResultUrlRegistryServiceTrackerCustomizer implements protected abstract ScoreCorrectionProvider configureScoreCorrectionProvider(ResultUrlRegistry resultUrlRegistry); + // return null by default to not to create create dependency on competitor import in freg and yachtscoring since we haven't + // had implementation for importing competitors for this bundles yet protected CompetitorProvider configureCompetitorProvider(ResultUrlRegistry resultUrlRegistry) { return null; } From e8cf8acd29e9dcb06ce02c33d9c80abcad24213d Mon Sep 17 00:00:00 2001 From: Alexander Tatarinovich Date: Wed, 16 Nov 2016 13:53:32 +0300 Subject: [PATCH 014/214] bug3246: add callback for saving and registering competitors Change-Id: I8ac14af5c263b5e2fb4293d9ad712164d214f46b --- ...mpetitorImportProviderSelectionDialog.java | 26 +++++------ .../gwt/ui/adminconsole/CompetitorPanel.java | 18 ++++---- .../ImportCompetitorCallback.java | 45 +++++++++++++++++++ ...va => MatchImportedCompetitorsDialog.java} | 21 +++------ 4 files changed, 74 insertions(+), 36 deletions(-) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ImportCompetitorCallback.java rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/{ApplyImportedCompetitorsDialog.java => MatchImportedCompetitorsDialog.java} (93%) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java index 13822ecbfe3..208902443bf 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorImportProviderSelectionDialog.java @@ -28,8 +28,8 @@ import com.sap.sse.gwt.client.dialog.DataEntryDialog; /** * Defines the dialog for displaying competitor provider names and list box of pair "event, regatta" names where we have - * competitors are available for importing. Also defines which dialog would be created for matching and applying result - * of import using the factory {@link ApplyImportedCompetitorsDialogFactory} + * competitors are available for importing. Also defines which dialog would be created for matching imported competitors + * using the factory {@link MatchImportedCompetitorsDialogFactory} * * @author Alexander_Tatarinovich * @@ -49,11 +49,11 @@ public class CompetitorImportProviderSelectionDialog extends DataEntryDialog> eventRagateNamesByCompetitorListItem; - public CompetitorImportProviderSelectionDialog(ApplyImportedCompetitorsDialogFactory applyCompetitorsDialogFactory, + public CompetitorImportProviderSelectionDialog(MatchImportedCompetitorsDialogFactory matchCompetitorsDialogFactory, Busyness busynessPanel, Iterable competitorProviderNames, SailingServiceAsync sailingService, StringMessages stringMessages, ErrorReporter errorReporter) { super(stringMessages.importCompetitors(), null, stringMessages.ok(), stringMessages.cancel(), null, - new Callback(applyCompetitorsDialogFactory, sailingService, busynessPanel, errorReporter, + new Callback(matchCompetitorsDialogFactory, sailingService, busynessPanel, errorReporter, stringMessages)); this.sailingService = sailingService; this.stringMessages = stringMessages; @@ -162,16 +162,16 @@ public class CompetitorImportProviderSelectionDialog extends DataEntryDialog competitors) { busynessPanel.setBusy(false); - applyCompetitorsDialogFactory - .createApplyImportedCompetitorsDialog(competitorDescriptors, competitors) + matchCompetitorsDialogFactory + .createMatchImportedCompetitorsDialog(competitorDescriptors, competitors) .show(); } }); @@ -222,8 +222,8 @@ public class CompetitorImportProviderSelectionDialog extends DataEntryDialog competitorDescriptors, Iterable competitors); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java index e9f98d83ea2..0f2f9580a57 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorPanel.java @@ -14,7 +14,7 @@ import com.google.gwt.view.client.SelectionChangeEvent.Handler; import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.CompetitorDTOImpl; import com.sap.sailing.domain.common.dto.CompetitorDescriptorDTO; -import com.sap.sailing.gwt.ui.adminconsole.CompetitorImportProviderSelectionDialog.ApplyImportedCompetitorsDialogFactory; +import com.sap.sailing.gwt.ui.adminconsole.CompetitorImportProviderSelectionDialog.MatchImportedCompetitorsDialogFactory; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sse.gwt.client.ErrorReporter; @@ -102,11 +102,11 @@ public class CompetitorPanel extends SimplePanel implements Busyness{ sailingService.getCompetitorProviderNames(new AsyncCallback>() { @Override public void onSuccess(Iterable providerNames) { - ApplyImportedCompetitorsDialogFactory applyCompetitorsDialogFactory = getApplyCompetitorsDialogFactory( + MatchImportedCompetitorsDialogFactory matchCompetitorsDialogFactory = getMatchCompetitorsDialogFactory( sailingService, stringMessages, errorReporter); CompetitorImportProviderSelectionDialog dialog = new CompetitorImportProviderSelectionDialog( - applyCompetitorsDialogFactory, CompetitorPanel.this, providerNames, sailingService, + matchCompetitorsDialogFactory, CompetitorPanel.this, providerNames, sailingService, stringMessages, errorReporter); dialog.show(); } @@ -153,16 +153,18 @@ public class CompetitorPanel extends SimplePanel implements Busyness{ } } - private ApplyImportedCompetitorsDialogFactory getApplyCompetitorsDialogFactory( + private MatchImportedCompetitorsDialogFactory getMatchCompetitorsDialogFactory( final SailingServiceAsync sailingService, final StringMessages stringMessages, final ErrorReporter errorReporter) { - return new ApplyImportedCompetitorsDialogFactory() { + return new MatchImportedCompetitorsDialogFactory() { @Override - public ApplyImportedCompetitorsDialog createApplyImportedCompetitorsDialog( + public MatchImportedCompetitorsDialog createMatchImportedCompetitorsDialog( final Iterable competitorDescriptors, final Iterable competitors) { - return new ApplyImportedCompetitorsDialog(competitorDescriptors, competitors, stringMessages, - sailingService, errorReporter); + ImportCompetitorCallback importCompetitorCallback = new ImportCompetitorCallback(sailingService, + errorReporter, stringMessages); + return new MatchImportedCompetitorsDialog(competitorDescriptors, competitors, stringMessages, + sailingService, errorReporter, importCompetitorCallback); } }; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ImportCompetitorCallback.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ImportCompetitorCallback.java new file mode 100644 index 00000000000..4593bcada4a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ImportCompetitorCallback.java @@ -0,0 +1,45 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import java.util.Set; + +import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.gwt.client.ErrorReporter; +import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback; + +/** + * Ńallback is responsible for saving competitors in store and registering them if necessary. + * Logic for registering should be implemented in child's classes. + * @author Alexander_Tatarinovich + * + */ +public class ImportCompetitorCallback implements DialogCallback> { + private final SailingServiceAsync sailingService; + private final ErrorReporter errorReporter; + private final StringMessages stringMessages; + + public ImportCompetitorCallback(SailingServiceAsync sailingService, ErrorReporter errorReporter, + StringMessages stringMessages) { + this.sailingService = sailingService; + this.errorReporter = errorReporter; + this.stringMessages = stringMessages; + } + + @Override + public void ok(Set competitorDTOs) { + saveCompetitors(competitorDTOs); + } + + @Override + public void cancel() { + } + + private void saveCompetitors(Set competitorDTOs) { + // TODO: implement logic for saving competitors + } + + protected void registerCompetitors(Set competitorDTOs) { + + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/MatchImportedCompetitorsDialog.java similarity index 93% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/MatchImportedCompetitorsDialog.java index 12d397e8da6..0eac6480402 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ApplyImportedCompetitorsDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/MatchImportedCompetitorsDialog.java @@ -24,12 +24,12 @@ import com.sap.sse.gwt.client.celltable.RefreshableSingleSelectionModel; import com.sap.sse.gwt.client.dialog.DataEntryDialog; /** - * Define dialog where we can match and apply imported competitors. + * Defines dialog where we can match and choose imported competitors. * * @author Alexander_Tatarinovich * */ -public class ApplyImportedCompetitorsDialog extends DataEntryDialog> { +public class MatchImportedCompetitorsDialog extends DataEntryDialog> { private CompetitorDescriptorTableWrapper> importedCompetitorsTable; private CompetitorTableWrapper> existingCompetitorsTable; @@ -43,11 +43,12 @@ public class ApplyImportedCompetitorsDialog extends DataEntryDialog existingCompetitorsByImported = new HashMap<>(); - public ApplyImportedCompetitorsDialog(final Iterable competitorDescriptorDTOs, + public MatchImportedCompetitorsDialog(final Iterable competitorDescriptorDTOs, final Iterable existingCompetitor, StringMessages stringMessages, - SailingServiceAsync sailingService, ErrorReporter errorReporter) { + SailingServiceAsync sailingService, ErrorReporter errorReporter, + DialogCallback> callback) { super(stringMessages.importCompetitors(), stringMessages.chooseWhichCompetitorsShouldBeImported(), - stringMessages.ok(), stringMessages.cancel(), null, /* TODO: implement calback */null); + stringMessages.ok(), stringMessages.cancel(), null, callback); this.stringMessages = stringMessages; this.sailingService = sailingService; this.errorReporter = errorReporter; @@ -138,16 +139,6 @@ public class ApplyImportedCompetitorsDialog extends DataEntryDialog competitors) { - // TODO: implement logic for saving competitors - - registerCompetitors(competitors); - } - - protected void registerCompetitors(Set competitors) { - // Do nothing by default. Can be overridden in child classes for registration competitor in race or regatta - } - @Override protected Set getResult() { final Set competitorsForSave = new HashSet<>(); From 8b7f42dad0aae454ce799ea660fe4f7e43c74fb4 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Tue, 22 Nov 2016 10:19:27 +0100 Subject: [PATCH 015/214] refactor signal quality view to show red/orange/green indicator --- .../res/values/colors.xml | 5 + .../shared/ui/customviews/GPSQuality.java | 26 ++++ .../SignalQualityIndicatorView.java | 137 +++++++++++------- .../app/services/TrackingService.java | 15 +- .../app/ui/activities/TrackingActivity.java | 6 +- .../app/ui/fragments/TrackingFragment.java | 6 +- .../app/ui/fragments/BuoyFragment.java | 23 +-- 7 files changed, 124 insertions(+), 94 deletions(-) create mode 100644 mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/GPSQuality.java diff --git a/mobile/com.sap.sailing.android.shared/res/values/colors.xml b/mobile/com.sap.sailing.android.shared/res/values/colors.xml index b8b85ffe5ec..56728497ca6 100644 --- a/mobile/com.sap.sailing.android.shared/res/values/colors.xml +++ b/mobile/com.sap.sailing.android.shared/res/values/colors.xml @@ -63,4 +63,9 @@ #f3f3f3 #bfbfbf + + #8ab54e + @color/sap_yellow + @color/sap_red + #455B27 diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/GPSQuality.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/GPSQuality.java new file mode 100644 index 00000000000..a121e993595 --- /dev/null +++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/GPSQuality.java @@ -0,0 +1,26 @@ +package com.sap.sailing.android.shared.ui.customviews; + +public enum GPSQuality { + noSignal(0), poor(2), good(3), great(4); + + private final int mQuality; + + GPSQuality(int quality) { + mQuality = quality; + } + + public int toInt() { + return this.mQuality; + } + + public static GPSQuality getValue(int value) { + GPSQuality result = null; + for (GPSQuality item : GPSQuality.values()) { + if (item.toInt() == value) { + result = item; + break; + } + } + return result; + } +} \ No newline at end of file diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/SignalQualityIndicatorView.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/SignalQualityIndicatorView.java index 002e2a4fbb6..469741f7b35 100644 --- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/SignalQualityIndicatorView.java +++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/customviews/SignalQualityIndicatorView.java @@ -3,7 +3,6 @@ package com.sap.sailing.android.shared.ui.customviews; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.text.TextUtils; @@ -14,17 +13,19 @@ import android.view.accessibility.AccessibilityEvent; import com.sap.sailing.android.shared.R; /** - * Draws one vertical indicator that can is filled green up to a point, depending on the value passed for - * signal-quality; + * Draws one vertical indicator that is colored depending on the signal quality * * @author Lukas Zielinski + * @author Peter Siegmund */ public class SignalQualityIndicatorView extends View { - private int signalQuality; + private GPSQuality mSignalQuality; - private Paint paint; - private Paint paintDark; + private Paint paintNone; + private Paint paintPoor; + private Paint paintGood; + private Paint paintGreat; private float height; private float width; @@ -35,7 +36,10 @@ public class SignalQualityIndicatorView extends View { TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SignalQualityIndicatorView, 0, 0); try { - signalQuality = a.getInteger(R.styleable.SignalQualityIndicatorView_signalQuality, 0); + mSignalQuality = GPSQuality.getValue(a.getInteger(R.styleable.SignalQualityIndicatorView_signalQuality, 0)); + if (mSignalQuality == null) { + mSignalQuality = GPSQuality.noSignal; + } } finally { a.recycle(); } @@ -44,52 +48,69 @@ public class SignalQualityIndicatorView extends View { initPaint(); } - public Integer getSignalQuality() { - return signalQuality; + public int getSignalQuality() { + return mSignalQuality.toInt(); } private void setAccessibilityString() { - if (this.signalQuality == 2) { - this.setContentDescription(getContext().getString(R.string.signal_accuracy_indicator_view_description) - + getContext().getString(R.string.poor)); - } else if (this.signalQuality == 3) { - this.setContentDescription(getContext().getString(R.string.signal_accuracy_indicator_view_description) - + getContext().getString(R.string.good)); - } else if (this.signalQuality == 4) { - this.setContentDescription(getContext().getString(R.string.signal_accuracy_indicator_view_description) - + getContext().getString(R.string.great)); - } else { - this.setContentDescription(getContext().getString(R.string.signal_accuracy_indicator_view_description) - + getContext().getString(R.string.no_signal)); + String desc = getContext().getString(R.string.signal_accuracy_indicator_view_description) + " "; + switch (mSignalQuality) { + case poor: + desc += getContext().getString(R.string.poor); + break; + + case good: + desc += getContext().getString(R.string.good); + break; + + case great: + desc += getContext().getString(R.string.great); + break; + + default: + desc += getContext().getString(R.string.no_signal); + } + setContentDescription(desc); } private void initPaint() { - paint = new Paint(Paint.ANTI_ALIAS_FLAG); - paint.setColor(Color.parseColor("#8ab54e")); - paintDark = new Paint(Paint.ANTI_ALIAS_FLAG); - paintDark.setColor(Color.parseColor("#455B27")); + paintNone = new Paint(Paint.ANTI_ALIAS_FLAG); + paintNone.setColor(getResources().getColor(R.color.signal_none)); + paintPoor = new Paint(Paint.ANTI_ALIAS_FLAG); + paintPoor.setColor(getResources().getColor(R.color.signal_poor)); + paintGood = new Paint(Paint.ANTI_ALIAS_FLAG); + paintGood.setColor(getResources().getColor(R.color.signal_good)); + paintGreat = new Paint(Paint.ANTI_ALIAS_FLAG); + paintGreat.setColor(getResources().getColor(R.color.signal_great)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - float boxHeight = this.height / 4; - // first draw gray background + Paint paint; + switch (mSignalQuality) { + case poor: + paint = paintPoor; + break; + + case good: + paint = paintGood; + break; + + case great: + paint = paintGreat; + break; + + default: + paint = paintNone; + } rect.top = 0; rect.left = 0; rect.right = (int) this.width; rect.bottom = (int) this.height; - canvas.drawRect(rect, paintDark); - - // then draw green box on top - - rect.top = (int) (this.height - (signalQuality * boxHeight)); - rect.left = 0; - rect.right = (int) this.width; - rect.bottom = (int) this.height; canvas.drawRect(rect, paint); } @@ -116,24 +137,17 @@ public class SignalQualityIndicatorView extends View { /** * Must be 0,2,3 or 4, otherwise 1 will be set * - * @param signalQuality + * @param signalQuality the new signal quality */ - public void setSignalQuality(Integer signalQuality) { - Integer previousSingalQuality = this.signalQuality; + public void setSignalQuality(GPSQuality signalQuality) { + GPSQuality previousSignalQuality = mSignalQuality; - if (signalQuality == 0) { - this.signalQuality = 0; - } else if (signalQuality == 2) { - this.signalQuality = 2; - } else if (signalQuality == 3) { - this.signalQuality = 3; - } else if (signalQuality == 4) { - this.signalQuality = 4; - } else { - this.signalQuality = 0; + mSignalQuality = signalQuality; + if (mSignalQuality == null) { + mSignalQuality = GPSQuality.noSignal; } - if (this.signalQuality != previousSingalQuality) { + if (mSignalQuality != previousSignalQuality) { sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); } @@ -155,13 +169,24 @@ public class SignalQualityIndicatorView extends View { * generate some accessibility info */ public String getAccessibilityText() { - if (this.signalQuality == 2) - return "poor signal quality"; - if (this.signalQuality == 3) - return "good signal quality"; - if (this.signalQuality == 4) - return "great signal quality"; - return "no signal"; + String result; + switch (mSignalQuality) { + case poor: + result = "poor signal quality"; + break; + + case good: + result = "good signal quality"; + break; + + case great: + result = "great signal quality"; + break; + + default: + result = "no signal"; + } + return result; } @Override diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java index 5cd6902a837..1d505bc6290 100755 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java @@ -14,6 +14,7 @@ import org.json.JSONObject; import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.services.sending.MessageSendingService; +import com.sap.sailing.android.shared.ui.customviews.GPSQuality; import com.sap.sailing.android.tracking.app.BuildConfig; import com.sap.sailing.android.tracking.app.R; import com.sap.sailing.android.tracking.app.ui.activities.TrackingActivity; @@ -384,20 +385,6 @@ public class TrackingService extends Service implements android.location.Locati } } - public enum GPSQuality { - noSignal(0), poor(2), good(3), great(4); - - private final int gpsQuality; - - GPSQuality(int quality) { - this.gpsQuality = quality; - } - - public int toInt() { - return this.gpsQuality; - } - } - public interface GPSQualityListener { void gpsQualityAndAccuracyUpdated(GPSQuality quality, float gpsAccurracy, Bearing gpsBearing, Speed gpsSpeed); diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java index 478fd24ffb2..7e405c7a623 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java @@ -25,10 +25,10 @@ import com.sap.sailing.android.shared.services.sending.MessageSendingService; import com.sap.sailing.android.shared.services.sending.MessageSendingService.APIConnectivity; import com.sap.sailing.android.shared.services.sending.MessageSendingService.APIConnectivityListener; import com.sap.sailing.android.shared.services.sending.MessageSendingService.MessageSendingBinder; +import com.sap.sailing.android.shared.ui.customviews.GPSQuality; import com.sap.sailing.android.tracking.app.BuildConfig; import com.sap.sailing.android.tracking.app.R; import com.sap.sailing.android.tracking.app.services.TrackingService; -import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQuality; import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQualityListener; import com.sap.sailing.android.tracking.app.services.TrackingService.TrackingBinder; import com.sap.sailing.android.tracking.app.ui.fragments.CompassFragment; @@ -242,9 +242,9 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener } @Override - public void gpsQualityAndAccuracyUpdated(GPSQuality quality, float gpsAccurracy, Bearing bearing, Speed speed) { + public void gpsQualityAndAccuracyUpdated(GPSQuality quality, float accuracy, Bearing bearing, Speed speed) { if (trackingFragment.isAdded()) { - trackingFragment.setGPSQualityAndAcurracy(quality, gpsAccurracy); + trackingFragment.setGPSQualityAndAcurracy(quality, accuracy); } ScreenSlidePagerAdapter viewPagerAdapter = getViewPagerAdapter(); diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java index e49bb5840a2..36eb39f45e6 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java @@ -18,12 +18,12 @@ import android.widget.Toast; import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.services.sending.MessageSendingService.APIConnectivity; +import com.sap.sailing.android.shared.ui.customviews.GPSQuality; import com.sap.sailing.android.shared.ui.customviews.SignalQualityIndicatorView; import com.sap.sailing.android.shared.util.LocationHelper; import com.sap.sailing.android.tracking.app.BuildConfig; import com.sap.sailing.android.tracking.app.R; import com.sap.sailing.android.tracking.app.services.TrackingService; -import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQuality; import com.sap.sailing.android.tracking.app.ui.activities.TrackingActivity; import com.sap.sailing.android.tracking.app.utils.AppPreferences; @@ -91,7 +91,7 @@ public class TrackingFragment extends BaseFragment { modeText.setText(savedInstanceState.getString(SIS_MODE)); statusText.setText(savedInstanceState.getString(SIS_STATUS)); - qualityIndicator.setSignalQuality(savedInstanceState.getInt(SIS_GPS_QUALITY)); + qualityIndicator.setSignalQuality(GPSQuality.getValue(savedInstanceState.getInt(SIS_GPS_QUALITY))); accuracyText.setText(savedInstanceState.getString(SIS_GPS_ACCURACY)); unsentFixesText.setText(savedInstanceState.getString(SIS_GPS_UNSENT_FIXES)); } else { @@ -235,7 +235,7 @@ public class TrackingFragment extends BaseFragment { if (isAdded()) { Activity activity = getActivity(); SignalQualityIndicatorView indicatorView = (SignalQualityIndicatorView) activity.findViewById(R.id.gps_quality_indicator); - indicatorView.setSignalQuality(quality.toInt()); + indicatorView.setSignalQuality(quality); TextView accuracyTextView = (TextView) getActivity().findViewById(R.id.gps_accuracy_label); accuracyTextView.setText("~ " + String.valueOf(Math.round(gpsAccurracy)) + " m"); updateTrackingStatus(quality); diff --git a/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/BuoyFragment.java b/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/BuoyFragment.java index 19aa8d7dcae..466e689a658 100644 --- a/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/BuoyFragment.java +++ b/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/BuoyFragment.java @@ -33,6 +33,7 @@ import com.sap.sailing.android.buoy.positioning.app.valueobjects.MarkInfo; import com.sap.sailing.android.buoy.positioning.app.valueobjects.MarkPingInfo; import com.sap.sailing.android.shared.data.LeaderboardInfo; import com.sap.sailing.android.shared.logging.ExLog; +import com.sap.sailing.android.shared.ui.customviews.GPSQuality; import com.sap.sailing.android.shared.ui.customviews.SignalQualityIndicatorView; import com.sap.sailing.android.shared.util.LocationHelper; import com.sap.sailing.android.shared.util.ViewHelper; @@ -74,7 +75,7 @@ public class BuoyFragment extends BaseFragment setUpSetPositionButton(layout, clickListener); signalQualityIndicatorView = ViewHelper.get(layout, R.id.signal_quality_indicator); - signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal.toInt()); + signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal); mReceiver = new IntentReceiver(); mBroadcastManager = LocalBroadcastManager.getInstance(inflater.getContext()); @@ -101,7 +102,7 @@ public class BuoyFragment extends BaseFragment mapFragment.getMap().setMapType(GoogleMap.MAP_TYPE_SATELLITE); initialLocationUpdate = true; MarkInfo mark = positioningActivity.getMarkInfo(); - signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal.toInt()); + signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal); if (mark != null) { setUpTextUI(lastKnownLocation); GoogleMap map = mapFragment.getMap(); @@ -217,7 +218,7 @@ public class BuoyFragment extends BaseFragment //provider (GPS) disabled by the user while tracking disablePositionButton(); setUpTextUI(null); - signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal.toInt()); + signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal); LocationHelper.showNoGPSError(getActivity(), getString(R.string.enable_gps)); } @@ -257,7 +258,7 @@ public class BuoyFragment extends BaseFragment } else if (gpsAccuracy <= 10) { quality = GPSQuality.great; } - signalQualityIndicatorView.setSignalQuality(quality.toInt()); + signalQualityIndicatorView.setSignalQuality(quality); } private void handleSuccessfulResponse() { @@ -268,20 +269,6 @@ public class BuoyFragment extends BaseFragment pingListener = listener; } - private enum GPSQuality { - noSignal(0), poor(2), good(3), great(4); - - private final int gpsQuality; - - GPSQuality(int quality) { - this.gpsQuality = quality; - } - - public int toInt() { - return this.gpsQuality; - } - } - public interface pingListener { void updatePing(); } From 9caf3b3725ad2453f026d0da099087cfb8fc7ea3 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Wed, 23 Nov 2016 15:01:55 +0100 Subject: [PATCH 016/214] move TimeUtils into shared --- .../res/values-de/strings.xml | 3 +++ mobile/com.sap.sailing.android.shared/res/values/dimens.xml | 2 ++ .../com.sap.sailing.android.shared/res/values/strings.xml | 6 ++++++ .../src/com/sap/sailing/android/shared/util}/TimeUtils.java | 0 .../res/values-de/strings.xml | 3 --- .../res/values/strings.xml | 5 ----- .../app/ui/adapters/racelist/ManagedRaceListAdapter.java | 2 +- .../app/ui/fragments/dialogs/ProtestTimeDialogFragment.java | 2 +- .../app/ui/fragments/panels/FlagPanelFragment.java | 2 +- .../app/ui/fragments/panels/TimePanelFragment.java | 2 +- .../app/ui/fragments/raceinfo/MainScheduleFragment.java | 2 +- .../app/ui/fragments/raceinfo/MoreFlagsFragment.java | 2 +- .../app/ui/fragments/raceinfo/RaceFinishingFragment.java | 2 +- .../app/ui/fragments/raceinfo/RaceFlagViewerFragment.java | 2 +- .../app/ui/fragments/raceinfo/RaceSummaryFragment.java | 2 +- .../app/ui/fragments/raceinfo/RaceTimeChangeFragment.java | 2 +- .../app/ui/fragments/raceinfo/StartTimeFragment.java | 2 +- .../app/ui/fragments/raceinfo/WindFragment.java | 2 +- .../racecommittee/app/ui/layouts/CompetitorEditLayout.java | 2 +- 19 files changed, 24 insertions(+), 21 deletions(-) rename mobile/{com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils => com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util}/TimeUtils.java (100%) diff --git a/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml b/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml index b216087f400..8028c52fd27 100644 --- a/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml +++ b/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml @@ -57,4 +57,7 @@ Mehr Informationen auf https://www.sapsailing.com + Gestern + Heute + Morgen \ No newline at end of file diff --git a/mobile/com.sap.sailing.android.shared/res/values/dimens.xml b/mobile/com.sap.sailing.android.shared/res/values/dimens.xml index ec8dcb461d3..dda2497c9ba 100644 --- a/mobile/com.sap.sailing.android.shared/res/values/dimens.xml +++ b/mobile/com.sap.sailing.android.shared/res/values/dimens.xml @@ -53,4 +53,6 @@ 21sp 18sp + 12dp + \ No newline at end of file diff --git a/mobile/com.sap.sailing.android.shared/res/values/strings.xml b/mobile/com.sap.sailing.android.shared/res/values/strings.xml index 2da6ef70149..51361221b34 100644 --- a/mobile/com.sap.sailing.android.shared/res/values/strings.xml +++ b/mobile/com.sap.sailing.android.shared/res/values/strings.xml @@ -81,4 +81,10 @@ More information on https://www.sapsailing.com + Yesterday + Today + Tomorrow + %1$dh %2$02d\' %3$02d\" + yyyy-MM-dd + \ No newline at end of file diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/TimeUtils.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/TimeUtils.java similarity index 100% rename from mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/TimeUtils.java rename to mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/TimeUtils.java diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml b/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml index 08b55413332..9b16f533906 100644 --- a/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml +++ b/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml @@ -171,7 +171,6 @@ Aktive Rennen Rennen planen Startmodus und Startzeit setzen - Heute Startzeit des Rennens setzen Nationalität Nummer @@ -337,7 +336,6 @@ Zeit setzen -%s %s - Morgen Beginn des Zieleinlaufs Aktuelle Zeit Individuelle Zeit @@ -426,7 +424,6 @@ Zielschiff-Wettfahrtleiter Regattaleitung an Land Demo-Modus - Gestern fortfahren Abbrechen Nach den Wettfahrtregeln sind diese Daten im aktuellen Rennenstatus nicht veränderbar.\nSie könnten jedoch die falschen Eingaben korrigieren. diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml index 5bf59b33498..51f09d04611 100644 --- a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml +++ b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml @@ -181,8 +181,6 @@ Show active Schedule race Select start mode and start time - Today - Tomorrow Set start time Nationality Number @@ -451,7 +449,6 @@ Race Officer on Finish Vessel Shore Control Viewer - Yesterday Proceed Cancel According to the race rules this data is not changeable in the current\nrace state. You may proceed nevertheless to correct wrong inputs. @@ -486,7 +483,6 @@ %.5f (since %s) - %1$dh %2$02d\' %3$02d\" Previous Course Course Layout ° @@ -525,7 +521,6 @@ North-based Heading Finishing Date - yyyy-MM-dd by Sail Id by Name diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/ManagedRaceListAdapter.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/ManagedRaceListAdapter.java index e63ec5752e0..a8bcaf4cd94 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/ManagedRaceListAdapter.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/ManagedRaceListAdapter.java @@ -13,6 +13,7 @@ import java.util.Set; import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.util.BitmapHelper; import com.sap.sailing.android.shared.util.BroadcastManager; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult; @@ -34,7 +35,6 @@ import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceFilter.FilterS import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources; import com.sap.sailing.racecommittee.app.utils.RaceHelper; import com.sap.sailing.racecommittee.app.utils.ThemeHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ProtestTimeDialogFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ProtestTimeDialogFragment.java index 55900bd2398..3ba59f3b0be 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ProtestTimeDialogFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ProtestTimeDialogFragment.java @@ -25,6 +25,7 @@ import android.widget.TimePicker; import com.sap.sailing.android.shared.util.BitmapHelper; import com.sap.sailing.android.shared.util.BroadcastManager; import com.sap.sailing.android.shared.util.ScreenHelper; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder; import com.sap.sailing.domain.base.racegroup.RaceGroupSeriesFleet; @@ -35,7 +36,6 @@ import com.sap.sailing.racecommittee.app.data.DataManager; import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager; import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.utils.ThemeHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/FlagPanelFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/FlagPanelFragment.java index 8fb8af67586..719651a2ac5 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/FlagPanelFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/FlagPanelFragment.java @@ -13,6 +13,7 @@ import android.view.ViewGroup; import android.widget.TextView; import com.sap.sailing.android.shared.logging.ExLog; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.impl.BaseRaceStateChangedListener; @@ -23,7 +24,6 @@ import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.AbortFlagsFragmen import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.EmptyFragment; import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.MoreFlagsFragment; import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RecallFlagsFragment; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; public class FlagPanelFragment extends BasePanelFragment { diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/TimePanelFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/TimePanelFragment.java index 78b8596c2ef..3ee63de81bb 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/TimePanelFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/panels/TimePanelFragment.java @@ -18,6 +18,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.sap.sailing.android.shared.logging.ExLog; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult; @@ -31,7 +32,6 @@ import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.StartTimeFragment import com.sap.sailing.racecommittee.app.ui.layouts.TimePanelHeaderLayout; import com.sap.sailing.racecommittee.app.utils.RaceHelper; import com.sap.sailing.racecommittee.app.utils.TickSingleton; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MainScheduleFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MainScheduleFragment.java index aad252bdc5f..ceddeb54ec8 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MainScheduleFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MainScheduleFragment.java @@ -14,6 +14,7 @@ import android.view.View; import android.view.ViewGroup; import com.sap.sailing.android.shared.logging.ExLog; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformationType; @@ -35,7 +36,6 @@ import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment; import com.sap.sailing.racecommittee.app.ui.fragments.chooser.RaceInfoFragmentChooser; import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources; import com.sap.sailing.racecommittee.app.utils.RaceHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MoreFlagsFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MoreFlagsFragment.java index 020b4c9af4e..54e6528c174 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MoreFlagsFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/MoreFlagsFragment.java @@ -14,6 +14,7 @@ import android.widget.TimePicker; import android.widget.Toast; import com.sap.sailing.android.shared.util.AppUtils; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; @@ -25,7 +26,6 @@ import com.sap.sailing.racecommittee.app.ui.adapters.MoreFlagsAdapter.MoreFlag; import com.sap.sailing.racecommittee.app.ui.adapters.MoreFlagsAdapter.MoreFlagItemClick; import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources; import com.sap.sailing.racecommittee.app.utils.ThemeHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFinishingFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFinishingFragment.java index 6d5d9aa6c42..094ec18e827 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFinishingFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFinishingFragment.java @@ -11,11 +11,11 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFlagViewerFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFlagViewerFragment.java index 83766fd0627..129fc4f416c 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFlagViewerFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceFlagViewerFragment.java @@ -14,6 +14,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.FlagPoleState; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; @@ -23,7 +24,6 @@ import com.sap.sailing.domain.common.racelog.FlagPole; import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java index aa706281192..cfbeafb6730 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java @@ -9,12 +9,12 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.common.Wind; import com.sap.sailing.racecommittee.app.R; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; public class RaceSummaryFragment extends BaseFragment { diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceTimeChangeFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceTimeChangeFragment.java index 15a56a23ca9..539b14617e2 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceTimeChangeFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceTimeChangeFragment.java @@ -16,13 +16,13 @@ import android.widget.TimePicker; import android.widget.Toast; import com.sap.sailing.android.shared.util.BroadcastManager; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.racecommittee.app.AppConstants; import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.domain.impl.Result; import com.sap.sailing.racecommittee.app.ui.layouts.HeaderLayout; import com.sap.sailing.racecommittee.app.utils.ThemeHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/StartTimeFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/StartTimeFragment.java index 74f74845533..1237f15bbc9 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/StartTimeFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/StartTimeFragment.java @@ -12,6 +12,7 @@ import java.util.Map; import com.sap.sailing.android.shared.util.AppUtils; import com.sap.sailing.android.shared.util.BitmapHelper; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult; @@ -31,7 +32,6 @@ import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.ui.adapters.DependentRaceSpinnerAdapter; import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment; import com.sap.sailing.racecommittee.app.utils.ThemeHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java index 137aebe2348..c701a73a6ae 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java @@ -17,6 +17,7 @@ import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.util.AppUtils; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.base.racegroup.CurrentRaceComparator; import com.sap.sailing.domain.base.racegroup.CurrentRaceFilter; @@ -43,7 +44,6 @@ import com.sap.sailing.racecommittee.app.utils.GeoUtils; import com.sap.sailing.racecommittee.app.utils.RaceHelper; import com.sap.sailing.racecommittee.app.utils.RangeInputFilter; import com.sap.sailing.racecommittee.app.utils.ThemeHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sailing.racecommittee.app.utils.WindHelper; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/layouts/CompetitorEditLayout.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/layouts/CompetitorEditLayout.java index 2a27656bd61..58f77420d05 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/layouts/CompetitorEditLayout.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/layouts/CompetitorEditLayout.java @@ -20,6 +20,7 @@ import android.widget.ScrollView; import android.widget.Spinner; import com.sap.sailing.android.shared.util.AppUtils; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.CompetitorResult; import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultImpl; @@ -28,7 +29,6 @@ import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.domain.impl.CompetitorResultWithIdImpl; import com.sap.sailing.racecommittee.app.ui.adapters.StringArraySpinnerAdapter; import com.sap.sailing.racecommittee.app.utils.ThemeHelper; -import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; From fa5d084800fe7e2efa9e56f3db24b0c0a35b531b Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Wed, 23 Nov 2016 15:02:17 +0100 Subject: [PATCH 017/214] fixed lint blocker --- .../AndroidManifest.xml | 9 --------- .../res/values/preferences.xml | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml b/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml index 2db55bedcc6..8d92daee5b3 100644 --- a/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml +++ b/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml @@ -128,15 +128,6 @@ - - - - - - - diff --git a/mobile/com.sap.sailing.android.tracking.app/res/values/preferences.xml b/mobile/com.sap.sailing.android.tracking.app/res/values/preferences.xml index a388bca7356..6fcbb122248 100644 --- a/mobile/com.sap.sailing.android.tracking.app/res/values/preferences.xml +++ b/mobile/com.sap.sailing.android.tracking.app/res/values/preferences.xml @@ -16,7 +16,7 @@ Choose a value as high as possible to preserve battery life while still maintaining a reasonable live experience, depending on your use case. GPS updates will be sent to the server%1$s %2$s. - msgSndIntMessage + msgSndIntMessage every immediately From 7553dcbcf1a728e4cc176ace9cfffd1090437789 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Wed, 23 Nov 2016 16:46:41 +0100 Subject: [PATCH 018/214] usage of plural resources --- .../res/layout-land/fragment_regatta.xml | 3 --- .../res/layout/fragment_regatta.xml | 3 --- .../res/values-de/strings.xml | 18 ++++++++++----- .../res/values/strings.xml | 18 ++++++++++----- .../app/ui/fragments/RegattaFragment.java | 22 ++++--------------- 5 files changed, 28 insertions(+), 36 deletions(-) diff --git a/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_regatta.xml b/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_regatta.xml index 50e25da203f..b2a14d3ab7d 100644 --- a/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_regatta.xml +++ b/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_regatta.xml @@ -301,7 +301,6 @@ android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:padding="0dp" - android:text="@string/days" android:singleLine="true" android:textColor="@color/white"/> @@ -332,7 +331,6 @@ android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:padding="0dp" - android:text="@string/hours" android:singleLine="true" android:textColor="@color/white"/> @@ -363,7 +361,6 @@ android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:padding="0dp" - android:text="@string/minutes" android:singleLine="true" android:textColor="@color/white"/> diff --git a/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_regatta.xml b/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_regatta.xml index bc6493076c8..f7c86bf2ba7 100644 --- a/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_regatta.xml +++ b/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_regatta.xml @@ -305,7 +305,6 @@ android:layout_height="wrap_content" android:padding="0dp" android:singleLine="true" - android:text="@string/days" android:textColor="@color/fiori_text_color" android:textSize="@dimen/default_text_size"/> @@ -343,7 +342,6 @@ android:layout_height="wrap_content" android:padding="0dp" android:singleLine="true" - android:text="@string/hours" android:textColor="@color/fiori_text_color" android:textSize="@dimen/default_text_size"/> @@ -380,7 +378,6 @@ android:layout_height="wrap_content" android:padding="0dp" android:singleLine="true" - android:text="@string/minutes" android:textColor="@color/fiori_text_color" android:textSize="@dimen/default_text_size"/> diff --git a/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml b/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml index 314a1aa3a66..1d3941827eb 100644 --- a/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml +++ b/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml @@ -44,12 +44,18 @@ Konnte Operation nicht durchfĂĽhren. Bitte versuchen Sie es noch einmal. Fehler: Konnte Team-Foto nicht an den server senden. Regatta beginnt in: - Stunden - Minute - Minuten - Tage - Stunde - Tag + + Stunde + Stunden + + + Minute + Minuten + + + Tag + Tage + Bitte achten Sie auf die Durchsagen Sie haben keinen QR-Code? QR-Code scannen diff --git a/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml b/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml index c9a17a606d9..79e408f2280 100644 --- a/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml +++ b/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml @@ -35,12 +35,18 @@ Could not complete operation on server. Please try again. Error: Could not send team image to server. Regatta starts in: - Hours - Minutes - Days - Hour - Minute - Day + + Hour + Hours + + + Minute + Minutes + + + Day + Days + Please listen to announcements Close Thank you! You have successfully taken part in the regatta.\n\nYour SAP Sailing Team diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java index 2c3c98f36bd..a1a48c5e71e 100755 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java @@ -370,27 +370,13 @@ public class RegattaFragment extends BaseFragment implements OnClickListener { TextView hoursTextViewLabel = (TextView) getActivity().findViewById(R.id.starts_in_hours_label); TextView minutesTextViewLabel = (TextView) getActivity().findViewById(R.id.starts_in_minutes_label); + daysTextViewLabel.setText(getResources().getQuantityText(R.plurals.day, days)); + hoursTextViewLabel.setText(getResources().getQuantityText(R.plurals.hour, hours)); + minutesTextViewLabel.setText(getResources().getQuantityText(R.plurals.minute, minutes)); + daysTextView.setText(String.format("%02d", days)); hoursTextView.setText(String.format("%02d", hours)); minutesTextView.setText(String.format("%02d", minutes)); - - if (days == 1) { - daysTextViewLabel.setText(R.string.day); - } else { - daysTextViewLabel.setText(R.string.days); - } - - if (hours == 1) { - hoursTextViewLabel.setText(R.string.hour); - } else { - hoursTextViewLabel.setText(R.string.hours); - } - - if (minutes == 1) { - minutesTextViewLabel.setText(R.string.minute); - } else { - minutesTextViewLabel.setText(R.string.minutes); - } } public void setFragmentWatcher(FragmentWatcher fWatcher) { From fcecf7501b79456091cf4b92539634f4953432c7 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Thu, 24 Nov 2016 15:41:45 +0100 Subject: [PATCH 019/214] =?UTF-8?q?reset=20to=20=E2=80=9Cno=20gps=E2=80=9D?= =?UTF-8?q?=20after=205=20sec=20without=20any=20onLocationChanged=20call?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/shared/util/TimeUtils.java | 4 +- .../android/shared/util/UniqueDeviceUuid.java | 2 +- .../res/values-de/strings.xml | 4 +- .../res/values/strings_fragment.xml | 4 +- .../app/services/TrackingService.java | 166 +++++++++++------ .../app/ui/activities/TrackingActivity.java | 121 +++---------- .../app/ui/fragments/RegattaFragment.java | 3 + .../app/ui/fragments/TrackingFragment.java | 168 +++++++----------- .../ui/fragments/TrackingTimeFragment.java | 100 +++++++++-- 9 files changed, 294 insertions(+), 278 deletions(-) diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/TimeUtils.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/TimeUtils.java index af4c38f07cc..9d6252b1e93 100644 --- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/TimeUtils.java +++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/TimeUtils.java @@ -1,4 +1,4 @@ -package com.sap.sailing.racecommittee.app.utils; +package com.sap.sailing.android.shared.util; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -14,7 +14,7 @@ import android.widget.NumberPicker; import android.widget.TextView; import android.widget.TimePicker; -import com.sap.sailing.racecommittee.app.R; +import com.sap.sailing.android.shared.R; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/UniqueDeviceUuid.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/UniqueDeviceUuid.java index a3eb892e352..08c3ce11852 100644 --- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/UniqueDeviceUuid.java +++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/UniqueDeviceUuid.java @@ -14,7 +14,7 @@ public class UniqueDeviceUuid { private static String mDeviceId; - @SuppressLint("CommitPrefEdits") + @SuppressLint("ApplySharedPref") public synchronized static String getUniqueId(Context context) { if (mDeviceId == null) { SharedPreferences preferences = context.getSharedPreferences(FILENAME, Context.MODE_PRIVATE); diff --git a/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml b/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml index 1d3941827eb..d8184e12c03 100644 --- a/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml +++ b/mobile/com.sap.sailing.android.tracking.app/res/values-de/strings.xml @@ -22,8 +22,8 @@ Bitte bestätigen Soll das Tracking wirklich beendet werden? Tracking läuft - Kein GPS Signal! - Offline + Keine GPS Ă„nderungen oder Signal! + Initialisierung Modus Live Energie sparen diff --git a/mobile/com.sap.sailing.android.tracking.app/res/values/strings_fragment.xml b/mobile/com.sap.sailing.android.tracking.app/res/values/strings_fragment.xml index cf66464434a..c4357173b07 100644 --- a/mobile/com.sap.sailing.android.tracking.app/res/values/strings_fragment.xml +++ b/mobile/com.sap.sailing.android.tracking.app/res/values/strings_fragment.xml @@ -12,11 +12,11 @@ Unsent Messages Offline API-Error - Offline + Initialise Tracking Time Status Tracking - No GPS Signal! + No GPS Changes or Signal! Regatta User Image Add Photo Button GPS signal found! diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java index 1d505bc6290..093d349f782 100755 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/services/TrackingService.java @@ -1,5 +1,7 @@ package com.sap.sailing.android.tracking.app.services; +import static android.os.Process.THREAD_PRIORITY_BACKGROUND; + import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -10,7 +12,29 @@ import java.util.UUID; import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; +import org.json.JSONObject; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.BitmapFactory; +import android.hardware.GeomagneticField; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Binder; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.support.v4.app.NotificationCompat; +import android.widget.Toast; import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.services.sending.MessageSendingService; @@ -26,26 +50,19 @@ import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.MeterPerSecondSpeedImpl; import com.sap.sailing.domain.common.tracking.impl.FlatSmartphoneUuidAndGPSFixMovingJsonSerializer; +import com.sap.sse.common.Duration; -import android.annotation.TargetApi; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Intent; -import android.content.Context; -import android.graphics.BitmapFactory; -import android.hardware.GeomagneticField; -import android.location.Location; -import android.location.LocationManager; -import android.os.Binder; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.support.v4.app.NotificationCompat; -import android.widget.Toast; +public class TrackingService extends Service implements LocationListener { -public class TrackingService extends Service implements android.location.LocationListener { + private static final String TAG = TrackingService.class.getName(); + private static final String THREAD_NAME = "Location WatchDog"; + + private static final int NO_LOCATION = 0; + private static final long NO_LOCATION_CHECK = Duration.ONE_SECOND.times(5).asMillis(); + + private static final int POOR_DISTANCE = 48; + private static final int GREAT_DISTANCE = 10; + private static final int NO_DISTANCE = 0; private NotificationManager notificationManager; private AppPreferences prefs; @@ -53,8 +70,6 @@ public class TrackingService extends Service implements android.location.Locati private GPSQualityListener gpsQualityListener; private final IBinder trackingBinder = new TrackingBinder(); - private static final String TAG = TrackingService.class.getName(); - // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. private int NOTIFICATION_ID = R.string.tracker_started; @@ -62,12 +77,12 @@ public class TrackingService extends Service implements android.location.Locati public final static int UPDATE_INTERVAL_IN_MILLIS_DEFAULT = 1000; public final static String GPS_DISABLED_MESSAGE = "gpsDisabled"; private float minLocationUpdateDistanceInMeters = 0f; - private boolean initialLocation; private String checkinDigest; private EventInfo event; - protected LocationManager locationManager; + private LocationManager locationManager; + private LocationWatchDog locationWatchDog; /** * Must be synchronized upon while modifying the {@link #timerForDelayingSendingMessages} field @@ -80,7 +95,7 @@ public class TrackingService extends Service implements android.location.Locati * {@link #locationsQueuedBasedOnSendingInterval} after the send interval, and the next message sending intent * arriving can be forwarded to the sending service immediately, with the timer being started immediately afterwards * to delay the sending of messages arriving later until the resend interval has expired. If not {@code null}, - * messages that arrive in {@link #enqueueForSending(String, JSONObject)} will be appended to + * messages that arrive in {@link #enqueueForSending(String, Location)} will be appended to * {@link #locationsQueuedBasedOnSendingInterval}. *

* @@ -112,12 +127,8 @@ public class TrackingService extends Service implements android.location.Locati locationsQueuedBasedOnSendingInterval = new LinkedHashMap<>(); prefs = new AppPreferences(this); - initialLocation = true; notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); - - } @Override @@ -160,6 +171,18 @@ public class TrackingService extends Service implements android.location.Locati prefs.setTrackerIsTracking(true); prefs.setTrackerIsTrackingCheckinDigest(checkinDigest); + + if (locationWatchDog == null) { + // create new Location WatchDog + HandlerThread thread = new HandlerThread(THREAD_NAME, THREAD_PRIORITY_BACKGROUND); + thread.start(); + locationWatchDog = new LocationWatchDog(thread.getLooper()); + + // start WatchDog + Message msg = locationWatchDog.obtainMessage(NO_LOCATION); + msg.obj = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + locationWatchDog.sendMessageDelayed(msg, NO_LOCATION_CHECK); + } } private void stopTracking() { @@ -168,6 +191,12 @@ public class TrackingService extends Service implements android.location.Locati prefs.setTrackerIsTracking(false); prefs.setTrackerIsTrackingCheckinDigest(null); + if (locationWatchDog != null) { + // stop the Location WatchDog + locationWatchDog.getLooper().quit(); + locationWatchDog = null; + } + stopSelf(); ExLog.i(this, TAG, "Stopped Tracking"); } @@ -191,13 +220,15 @@ public class TrackingService extends Service implements android.location.Locati bearingImpl.add(new DegreeBearingImpl(- geomagneticField.getDeclination())); } - GPSQuality quality = GPSQuality.noSignal; if (gpsQualityListener != null) { - if (gpsAccuracy > 48) { + GPSQuality quality = GPSQuality.noSignal; + if (gpsAccuracy <= NO_DISTANCE) { + quality = GPSQuality.noSignal; + } else if (gpsAccuracy > POOR_DISTANCE) { quality = GPSQuality.poor; - } else if (gpsAccuracy > 10) { + } else if (gpsAccuracy > GREAT_DISTANCE) { quality = GPSQuality.good; - } else if (gpsAccuracy <= 10) { + } else if (gpsAccuracy <= GREAT_DISTANCE) { quality = GPSQuality.great; } @@ -205,7 +236,6 @@ public class TrackingService extends Service implements android.location.Locati } } - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) private JSONObject createJsonLocationFix(Location location) throws JSONException { JSONObject fixJson = new JSONObject(); fixJson.put(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.BEARING_DEG, location.getBearing()); @@ -215,7 +245,7 @@ public class TrackingService extends Service implements android.location.Locati fixJson.put(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.LAT_DEG, location.getLatitude()); return fixJson; } - + private JSONArray createJsonLocationFixes(Iterable locations) throws JSONException { final JSONArray fixesAsJson = new JSONArray(); for (final Location location : locations) { @@ -303,16 +333,7 @@ public class TrackingService extends Service implements android.location.Locati } }; } - - private void storeInitialTrackingTimestamp() { - if (prefs.getTrackingTimerStarted() == 0) { - prefs.setTrackingTimerStarted(System.currentTimeMillis()); - } - initialLocation = false; - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) @Override public IBinder onBind(Intent intent) { return trackingBinder; @@ -330,13 +351,18 @@ public class TrackingService extends Service implements android.location.Locati */ @Override public void onLocationChanged(Location location) { - if (initialLocation) { - storeInitialTrackingTimestamp(); - } reportGPSQualityBearingAndSpeed(location.getAccuracy(), location.getBearing(), location.getSpeed(), location.getLatitude(), location.getLongitude(), location.getAltitude()); final String postUrlStr = event.server + prefs.getServerGpsFixesPostPath(); enqueueForSending(postUrlStr, location); + + // clear message queue + locationWatchDog.removeMessages(NO_LOCATION); + + // add new message with last location + Message msg = locationWatchDog.obtainMessage(NO_LOCATION); + msg.obj = location; + locationWatchDog.sendMessageDelayed(msg, NO_LOCATION_CHECK); } @Override @@ -358,16 +384,17 @@ public class TrackingService extends Service implements android.location.Locati } private void showNotification() { - Intent intent = new Intent(this, TrackingActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP - | Intent.FLAG_ACTIVITY_SINGLE_TOP); - PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0); - Notification notification = new NotificationCompat.Builder(this) - .setContentTitle(getText(R.string.app_name)) - .setContentText(getString(R.string.tracking_notification_text, event.name)).setContentIntent(pi) - .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) - .setSmallIcon(R.drawable.ic_directions_boat) - .setOngoing(true).build(); + Intent intent = new Intent(this, TrackingActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0); + Notification notification = new NotificationCompat.Builder(this) + .setContentTitle(getText(R.string.app_name)) + .setContentText(getString(R.string.tracking_notification_text, event.name)) + .setContentIntent(pi) + .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) + .setSmallIcon(R.drawable.ic_directions_boat) + .setOngoing(true) + .build(); notificationManager.notify(NOTIFICATION_ID, notification); } @@ -386,8 +413,31 @@ public class TrackingService extends Service implements android.location.Locati } public interface GPSQualityListener { - void gpsQualityAndAccuracyUpdated(GPSQuality quality, float gpsAccurracy, Bearing gpsBearing, - Speed gpsSpeed); + void gpsQualityAndAccuracyUpdated(GPSQuality quality, float accuracy, Bearing bearing, Speed speed); } + private class LocationWatchDog extends Handler { + + LocationWatchDog(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case NO_LOCATION: + ExLog.i(getApplicationContext(), TAG, "No Location"); + Location location = (Location) msg.obj; + if (location == null) { + location = new Location(LocationManager.GPS_PROVIDER); + } + reportGPSQualityBearingAndSpeed(NO_DISTANCE, location.getBearing(), location.getSpeed(), + location.getLatitude(), location.getLongitude(), location.getAltitude()); + break; + + default: + super.handleMessage(msg); + } + } + } } \ No newline at end of file diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java index 7e405c7a623..808e4e2774f 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java @@ -17,7 +17,6 @@ import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.Button; -import android.widget.TextView; import com.sap.sailing.android.shared.data.LeaderboardInfo; import com.sap.sailing.android.shared.logging.ExLog; @@ -45,18 +44,17 @@ import com.viewpagerindicator.CirclePageIndicator; public class TrackingActivity extends BaseActivity implements GPSQualityListener, APIConnectivityListener { - TrackingService trackingService; + private TrackingService trackingService; private boolean trackingServiceBound; - private boolean gpsReceived; - MessageSendingService messageSendingService; + private MessageSendingService messageSendingService; boolean messageSendingServiceBound; private final static String TAG = TrackingActivity.class.getName(); - private final static String SIS_TRACKING_FRAGMENT = "savedInstanceTrackingFragment"; - private final static String SIS_LAST_VIEWPAGER_ITEM = "instanceStateLastViewPagerItem"; - private final static String SIS_LAST_SPEED_TEXT = "instanceStateLastSpeedText"; - private final static String SIS_LAST_COMPASS_TEXT = "instanceStateLastCompassText"; + private final static String SIS_TRACKING_FRAGMENT = "trackingFragment"; + private final static String SIS_LAST_VIEWPAGER_ITEM = "lastViewPagerItem"; + private final static String SIS_LAST_SPEED_TEXT = "lastSpeedText"; + private final static String SIS_LAST_COMPASS_TEXT = "lastCompassText"; private ViewPager mPager; private ScreenSlidePagerAdapter mPagerAdapter; @@ -65,7 +63,6 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener private String checkinDigest; private TrackingFragment trackingFragment; - private TimerRunnable timer; private int lastViewPagerItem; @@ -217,7 +214,6 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener @Override protected void onPause() { super.onPause(); - timer.stop(); mPager = (ViewPager) findViewById(R.id.pager); mPager.setAdapter(null); @@ -227,39 +223,38 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener protected void onResume() { super.onResume(); - timer = new TimerRunnable(); - Thread thread = new Thread(timer); - thread.start(); - if (mPagerAdapter == null) { mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); } mPager.setAdapter(mPagerAdapter); mPager.setCurrentItem(lastViewPagerItem); - - } @Override - public void gpsQualityAndAccuracyUpdated(GPSQuality quality, float accuracy, Bearing bearing, Speed speed) { - if (trackingFragment.isAdded()) { - trackingFragment.setGPSQualityAndAcurracy(quality, accuracy); - } + public void gpsQualityAndAccuracyUpdated(final GPSQuality quality, final float accuracy, final Bearing bearing, final Speed speed) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (trackingFragment.isAdded()) { + trackingFragment.setGPSQualityAndAccuracy(quality, accuracy); + } - ScreenSlidePagerAdapter viewPagerAdapter = getViewPagerAdapter(); + ScreenSlidePagerAdapter viewPagerAdapter = getViewPagerAdapter(); - if (viewPagerAdapter != null) { - SpeedFragment speedFragment = viewPagerAdapter.getSpeedFragment(); - if (speedFragment != null && speedFragment.isAdded()) { - speedFragment.setSpeed(speed); + if (viewPagerAdapter != null) { + SpeedFragment speedFragment = viewPagerAdapter.getSpeedFragment(); + if (speedFragment != null && speedFragment.isAdded()) { + speedFragment.setSpeed(speed); + } + + CompassFragment compassFragment = viewPagerAdapter.getCompassFragment(); + if (compassFragment != null && compassFragment.isAdded()) { + compassFragment.setBearing(bearing); + } + } } - - CompassFragment compassFragment = viewPagerAdapter.getCompassFragment(); - if (compassFragment != null && compassFragment.isAdded()) { - compassFragment.setBearing(bearing); - } - } + }); } @Override @@ -401,68 +396,4 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener ServiceHelper.getInstance().stopTrackingService(this); finish(); } - - /** - * Update UI with a string containing the time since tracking started, e.g. 01:22:45 - */ - public void updateTimer() { - long trackingTimerStarted = prefs.getTrackingTimerStarted(); - if (trackingTimerStarted > 0) { - hideWaitForGPSText(); - long diff = System.currentTimeMillis() - trackingTimerStarted; - TextView textView = (TextView) findViewById(R.id.tracking_time_label); - if (textView != null) { - textView.setText(getTimeFormatString(diff)); - } - } - } - - private void hideWaitForGPSText() { - if (!gpsReceived) { - View waitForGPSLabel = findViewById(R.id.wait_for_gps); - if (waitForGPSLabel != null) { - waitForGPSLabel.setVisibility(View.GONE); - gpsReceived = true; - } - } - } - - private String getTimeFormatString(long milliseconds) { - int seconds = (int) (milliseconds / 1000) % 60; - int minutes = (int) ((milliseconds / (1000 * 60)) % 60); - int hours = (int) ((milliseconds / (1000 * 60 * 60)) % 24); - - return String.format(getResources().getConfiguration().locale, "%02d:%02d:%02d", hours, minutes, seconds); - } - - private class TimerRunnable implements Runnable { - - private boolean running; - - TimerRunnable() { - running = true; - } - - @Override - public void run() { - while (running) { - runOnUiThread(new Runnable() { - @Override - public void run() { - trackingFragment.checkLastGPSReceived(); - updateTimer(); - } - }); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - ExLog.e(TrackingActivity.this, TAG, "Interrupted sleep"); - } - } - } - - public void stop() { - running = false; - } - } } diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java index a1a48c5e71e..592b53551e7 100755 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java @@ -37,6 +37,7 @@ import com.sap.sailing.android.tracking.app.ui.activities.RegattaActivity; import com.sap.sailing.android.tracking.app.ui.activities.TrackingActivity; import com.sap.sailing.android.tracking.app.utils.AppPreferences; import com.sap.sailing.android.tracking.app.valueobjects.EventInfo; +import com.sap.sse.common.impl.MillisecondsTimePoint; public class RegattaFragment extends BaseFragment implements OnClickListener { @@ -56,6 +57,7 @@ public class RegattaFragment extends BaseFragment implements OnClickListener { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.fragment_regatta, container, false); Button startTrackingButton = (Button) view.findViewById(R.id.start_tracking); @@ -333,6 +335,7 @@ public class RegattaFragment extends BaseFragment implements OnClickListener { } private void startTrackingActivity() { + prefs.setTrackingTimerStarted(MillisecondsTimePoint.now().asMillis()); RegattaActivity regattaActivity = (RegattaActivity) getActivity(); Intent intent = new Intent(getActivity(), TrackingActivity.class); String checkinDigest = regattaActivity.event.checkinDigest; diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java index 36eb39f45e6..4095f1fd5ba 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java @@ -1,11 +1,11 @@ package com.sap.sailing.android.tracking.app.ui.fragments; import android.annotation.TargetApi; -import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.location.LocationManager; import android.os.Build; import android.os.Bundle; import android.provider.Settings; @@ -16,12 +16,10 @@ import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; -import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.services.sending.MessageSendingService.APIConnectivity; import com.sap.sailing.android.shared.ui.customviews.GPSQuality; import com.sap.sailing.android.shared.ui.customviews.SignalQualityIndicatorView; import com.sap.sailing.android.shared.util.LocationHelper; -import com.sap.sailing.android.tracking.app.BuildConfig; import com.sap.sailing.android.tracking.app.R; import com.sap.sailing.android.tracking.app.services.TrackingService; import com.sap.sailing.android.tracking.app.ui.activities.TrackingActivity; @@ -29,25 +27,39 @@ import com.sap.sailing.android.tracking.app.utils.AppPreferences; public class TrackingFragment extends BaseFragment { - static final String SIS_MODE = "instanceStateMode"; - static final String SIS_STATUS = "instanceStateStatus"; - static final String SIS_GPS_QUALITY = "instanceStateGpsQuality"; - static final String SIS_GPS_ACCURACY = "instanceStateGpsAccuracy"; - static final String SIS_GPS_UNSENT_FIXES = "instanceStateGpsUnsentFixes"; + static final String SIS_MODE = "mode"; + static final String SIS_STATUS = "status"; + static final String SIS_GPS_ACCURACY = "gpsAccuracy"; + static final String SIS_GPS_UNSENT_FIXES = "gpsUnsentFixes"; - private long lastGPSQualityUpdate; private BroadcastReceiver gpsDisabledReceiver; - private Toast gpsToast; - private boolean gpsFound = true; - private String TAG = TrackingFragment.class.getName(); + private TextView modeText; + private TextView statusText; + private TextView accuracyText; + private TextView unsentFixesText; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - ViewGroup view = (ViewGroup) inflater.inflate(R.layout.fragment_tracking, container, false); + ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.fragment_tracking, container, false); prefs = new AppPreferences(getActivity()); - return view; + + modeText = (TextView) layout.findViewById(R.id.mode); + statusText = (TextView) layout.findViewById(R.id.tracking_status); + accuracyText = (TextView) layout.findViewById(R.id.gps_accuracy_label); + unsentFixesText = (TextView) layout.findViewById(R.id.tracking_unsent_fixes); + + if (savedInstanceState != null) { + modeText.setText(savedInstanceState.getString(SIS_MODE)); + statusText.setText(savedInstanceState.getString(SIS_STATUS)); + accuracyText.setText(savedInstanceState.getString(SIS_GPS_ACCURACY)); + unsentFixesText.setText(savedInstanceState.getString(SIS_GPS_UNSENT_FIXES)); + } else { + //initially set quality to "No GPS" on start tracking + updateTrackingStatus(GPSQuality.noSignal); + } + + return layout; } @Override @@ -75,62 +87,20 @@ public class TrackingFragment extends BaseFragment { @Override public void onStop() { super.onStop(); + getActivity().unregisterReceiver(gpsDisabledReceiver); - }; - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - if (savedInstanceState != null) { - TextView modeText = (TextView) getActivity().findViewById(R.id.mode); - TextView statusText = (TextView) getActivity().findViewById(R.id.tracking_status); - SignalQualityIndicatorView qualityIndicator = (SignalQualityIndicatorView) getActivity().findViewById( - R.id.gps_quality_indicator); - TextView accuracyText = (TextView) getActivity().findViewById(R.id.gps_accuracy_label); - TextView unsentFixesText = (TextView) getActivity().findViewById(R.id.tracking_unsent_fixes); - - modeText.setText(savedInstanceState.getString(SIS_MODE)); - statusText.setText(savedInstanceState.getString(SIS_STATUS)); - qualityIndicator.setSignalQuality(GPSQuality.getValue(savedInstanceState.getInt(SIS_GPS_QUALITY))); - accuracyText.setText(savedInstanceState.getString(SIS_GPS_ACCURACY)); - unsentFixesText.setText(savedInstanceState.getString(SIS_GPS_UNSENT_FIXES)); - } else { - //initially set quality to "No GPS" on start tracking - updateTrackingStatus(GPSQuality.noSignal); - } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - TextView modeText = (TextView) getActivity().findViewById(R.id.mode); - TextView statusText = (TextView) getActivity().findViewById(R.id.tracking_status); - SignalQualityIndicatorView qualityIndicator = (SignalQualityIndicatorView) getActivity().findViewById( - R.id.gps_quality_indicator); - TextView accuracyText = (TextView) getActivity().findViewById(R.id.gps_accuracy_label); - TextView unsentFixesText = (TextView) getActivity().findViewById(R.id.tracking_unsent_fixes); - outState.putString(SIS_MODE, modeText.getText().toString()); outState.putString(SIS_STATUS, statusText.getText().toString()); - outState.putInt(SIS_GPS_QUALITY, qualityIndicator.getSignalQuality()); outState.putString(SIS_GPS_ACCURACY, accuracyText.getText().toString()); outState.putString(SIS_GPS_UNSENT_FIXES, unsentFixesText.getText().toString()); } - /** - * If last GPS update is too long ago, let's assume there's no signal and set quality to .noSignal - */ - public void checkLastGPSReceived() { - if (System.currentTimeMillis() - lastGPSQualityUpdate > 3000 && !isLocationEnabled(getActivity())) { - if (BuildConfig.DEBUG) { - ExLog.i(getActivity(), TAG, - "Setting GPS Quality to 0 because timeout occurred and location is reported as disabled."); - } - setGPSQualityAndAcurracy(GPSQuality.noSignal, 0); - } - } - /** * Update tracking status string in UI * @@ -138,55 +108,44 @@ public class TrackingFragment extends BaseFragment { */ public void updateTrackingStatus(GPSQuality quality) { if (isAdded()) { - TextView textView = (TextView) getActivity().findViewById(R.id.tracking_status); if (quality == GPSQuality.noSignal) { - textView.setText(getString(R.string.tracking_status_no_gps_signal)); - textView.setTextColor(getResources().getColor(R.color.sap_red)); - //either GPS has been found before or tracking just started (but is not available now) --> show noGPS Toast - if (gpsFound || gpsToast == null) { - gpsToast = Toast.makeText(getActivity(),getString(R.string.tracking_status_no_gps_signal), Toast.LENGTH_LONG); - gpsToast.show(); - gpsFound = false; - } + statusText.setText(getString(R.string.tracking_status_no_gps_signal)); + statusText.setTextColor(getResources().getColor(R.color.sap_red)); } else { - textView.setText(getString(R.string.tracking_status_tracking)); - textView.setTextColor(getResources().getColor(R.color.fiori_text_color)); - if (gpsToast == null) { - gpsToast.cancel(); - } - //GPS was lost before but is available again now --> show gpsFound toast - if (!gpsFound) { - gpsToast = Toast.makeText(getActivity(),getString(R.string.tracking_status_gps_found), Toast.LENGTH_SHORT); - gpsToast.show(); - gpsFound = true; - } + statusText.setText(getString(R.string.tracking_status_tracking)); + statusText.setTextColor(getResources().getColor(R.color.fiori_text_color)); } } } /** * Update UI and tell user if app is caching or sending fixes to api - * - * @param apiConnectivity */ public void setAPIConnectivityStatus(final APIConnectivity apiConnectivity) { if (isAdded()) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { - TextView textView = (TextView) getActivity().findViewById(R.id.mode); - if (apiConnectivity == APIConnectivity.transmissionSuccess) { - textView.setText(getString(R.string.tracking_mode_live)); - textView.setTextColor(getResources().getColor(R.color.fiori_text_color)); - } else if (apiConnectivity == APIConnectivity.noAttempt) { - textView.setText(getString(R.string.tracking_mode_offline)); - textView.setTextColor(getResources().getColor(R.color.fiori_text_color)); - } else if (apiConnectivity == APIConnectivity.transmissionError) { - textView.setText(getString(R.string.tracking_mode_api_error)); - textView.setTextColor(getResources().getColor(R.color.sap_red)); - } else { - textView.setText(getString(R.string.tracking_mode_caching)); - textView.setTextColor(getResources().getColor(R.color.fiori_text_color)); + switch (apiConnectivity) { + case transmissionSuccess: + modeText.setText(getString(R.string.tracking_mode_live)); + modeText.setTextColor(getResources().getColor(R.color.fiori_text_color)); + break; + + case noAttempt: + modeText.setText(getString(R.string.tracking_mode_no_attempt)); + modeText.setTextColor(getResources().getColor(R.color.fiori_text_color)); + break; + + case transmissionError: + modeText.setText(getString(R.string.tracking_mode_api_error)); + modeText.setTextColor(getResources().getColor(R.color.sap_red)); + break; + + default: + modeText.setText(getString(R.string.tracking_mode_caching)); + modeText.setTextColor(getResources().getColor(R.color.fiori_text_color)); + } } }); @@ -209,7 +168,6 @@ public class TrackingFragment extends BaseFragment { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { try { locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE); - } catch (SettingNotFoundException e) { e.printStackTrace(); } @@ -219,7 +177,7 @@ public class TrackingFragment extends BaseFragment { } else { locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); - return locationProviders.contains("gps"); + return locationProviders.contains(LocationManager.GPS_PROVIDER); } } else { return false; @@ -231,15 +189,19 @@ public class TrackingFragment extends BaseFragment { activity.showStopTrackingConfirmationDialog(); } - public void setGPSQualityAndAcurracy(GPSQuality quality, float gpsAccurracy) { + public void setGPSQualityAndAccuracy(GPSQuality quality, float accuracy) { if (isAdded()) { - Activity activity = getActivity(); - SignalQualityIndicatorView indicatorView = (SignalQualityIndicatorView) activity.findViewById(R.id.gps_quality_indicator); - indicatorView.setSignalQuality(quality); - TextView accuracyTextView = (TextView) getActivity().findViewById(R.id.gps_accuracy_label); - accuracyTextView.setText("~ " + String.valueOf(Math.round(gpsAccurracy)) + " m"); - updateTrackingStatus(quality); - lastGPSQualityUpdate = System.currentTimeMillis(); + View layout = getView(); + if (layout != null) { + SignalQualityIndicatorView indicatorView = (SignalQualityIndicatorView) layout.findViewById(R.id.gps_quality_indicator); + indicatorView.setSignalQuality(quality); + updateTrackingStatus(quality); + if (quality != GPSQuality.noSignal) { + accuracyText.setText("~ " + Math.round(accuracy) + " m"); + } else { + accuracyText.setText(null); + } + } } } diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingTimeFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingTimeFragment.java index 86db635153a..02eaa424624 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingTimeFragment.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingTimeFragment.java @@ -1,51 +1,121 @@ package com.sap.sailing.android.tracking.app.ui.fragments; +import static android.os.Process.THREAD_PRIORITY_BACKGROUND; + +import android.app.Activity; +import android.content.Context; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.sap.sailing.android.shared.util.LocationHelper; +import com.sap.sailing.android.shared.util.TimeUtils; import com.sap.sailing.android.tracking.app.R; +import com.sap.sailing.android.tracking.app.utils.AppPreferences; +import com.sap.sse.common.Duration; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.impl.MillisecondsTimePoint; public class TrackingTimeFragment extends BaseFragment { - private final static String SIS_TRACKING_TIMER = "savedInstanceTrackingTimer"; + private static final String SIS_TRACKING_TIMER = "trackingTimer"; + private static final String THREAD_NAME = "Tracking Timer"; + + private static final int TIMER_SET = 0; + private static final long TIMER_DELAY = Duration.ONE_SECOND.asMillis(); + private TextView timerView; private TextView noGPSView; + private Handler handler; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - ViewGroup view = (ViewGroup) inflater.inflate(R.layout.fragment_time, container, false); - timerView = (TextView) view.findViewById(R.id.tracking_time_label); - noGPSView = (TextView) view.findViewById(R.id.wait_for_gps); - return view; + ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.fragment_time, container, false); + timerView = (TextView) layout.findViewById(R.id.tracking_time_label); + noGPSView = (TextView) layout.findViewById(R.id.wait_for_gps); + + if (savedInstanceState != null) { + timerView.setText(savedInstanceState.getString(SIS_TRACKING_TIMER)); + } + + return layout; } @Override public void onResume() { super.onResume(); + if (LocationHelper.isGPSEnabled(getActivity())) { noGPSView.setVisibility(View.GONE); } } @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - if (timerView != null) { - outState.putString(SIS_TRACKING_TIMER, timerView.getText().toString()); - } + public void onStart() { + super.onStart(); + + HandlerThread thread = new HandlerThread(THREAD_NAME, THREAD_PRIORITY_BACKGROUND); + thread.start(); + handler = new TimerHandler(thread.getLooper(), getActivity(), timerView); + handler.sendEmptyMessageDelayed(TIMER_SET, TIMER_DELAY); } @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onStop() { + super.onStop(); - if (savedInstanceState != null && timerView != null) { - timerView.setText(savedInstanceState.getString(SIS_TRACKING_TIMER)); + handler.getLooper().quit(); + handler.removeMessages(TIMER_SET); + handler = null; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + outState.putString(SIS_TRACKING_TIMER, timerView.getText().toString()); + } + + private static class TimerHandler extends Handler { + + private AppPreferences prefs; + private TextView timer; + + TimerHandler(Looper looper, Context context, TextView timer) { + super(looper); + this.prefs = new AppPreferences(context); + this.timer = timer; + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case TIMER_SET: + final long trackingTimerStarted = prefs.getTrackingTimerStarted(); + if (trackingTimerStarted > 0) { + final TimePoint now = MillisecondsTimePoint.now(); + if (timer != null) { + timer.post(new Runnable() { + @Override + public void run() { + timer.setText(TimeUtils.formatDurationSince(now.minus(trackingTimerStarted).asMillis())); + } + }); + } + } + sendEmptyMessageDelayed(TIMER_SET, TIMER_DELAY); + break; + + default: + super.handleMessage(msg); + } } } } From 40049a319cfa97717dbd55314f92e1466bc2fe34 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Mon, 28 Nov 2016 10:44:15 +0100 Subject: [PATCH 020/214] different RaceSummary layout for large font size (phone only) --- .../res/layout/race_summary_large_font.xml | 293 ++++++++++++++++++ ...ce_summary.xml => race_summary_normal.xml} | 0 .../raceinfo/RaceSummaryFragment.java | 7 +- 3 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary_large_font.xml rename mobile/com.sap.sailing.racecommittee.app/res/layout/{race_summary.xml => race_summary_normal.xml} (100%) diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary_large_font.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary_large_font.xml new file mode 100644 index 00000000000..0b7533a425a --- /dev/null +++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary_large_font.xml @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary_normal.xml similarity index 100% rename from mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary.xml rename to mobile/com.sap.sailing.racecommittee.app/res/layout/race_summary_normal.xml diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java index aa706281192..270d09e3f50 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/RaceSummaryFragment.java @@ -9,6 +9,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import com.sap.sailing.android.shared.util.AppUtils; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; @@ -37,7 +38,11 @@ public class RaceSummaryFragment extends BaseFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View layout = inflater.inflate(R.layout.race_summary, container, false); + int resId = R.layout.race_summary_normal; + if (AppUtils.with(inflater.getContext()).isPhone() && getResources().getConfiguration().fontScale > 1) { + resId = R.layout.race_summary_large_font; + } + View layout = inflater.inflate(resId, container, false); mRaceStateListener = new RaceStateListener(); mDateFormat = new SimpleDateFormat("HH:mm:ss", getResources().getConfiguration().locale); From 26178a6a84894e1e1263ba6d3669ff3583578f6c Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Mon, 28 Nov 2016 14:06:05 +0100 Subject: [PATCH 021/214] add displayName to leaderboards table --- .../android/shared/data/LeaderboardInfo.java | 1 + .../tracking/app/adapter/RegattaAdapter.java | 2 +- .../app/provider/AnalyticsContract.java | 72 +------ .../app/provider/AnalyticsDatabase.java | 22 +- .../app/provider/AnalyticsProvider.java | 199 +++++++++--------- .../app/ui/fragments/HomeFragment.java | 17 +- .../tracking/app/utils/AppPreferences.java | 4 - .../tracking/app/utils/CheckinManager.java | 40 ++-- .../tracking/app/utils/DatabaseHelper.java | 121 ++++------- .../tracking/app/utils/SqlDebugHelper.java | 75 ------- .../app/valueobjects/CheckinData.java | 3 + .../app/valueobjects/LeaderboardInfo.java | 8 - .../tracking/app/valueobjects/UrlData.java | 1 + 13 files changed, 196 insertions(+), 369 deletions(-) delete mode 100644 mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/SqlDebugHelper.java delete mode 100644 mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/LeaderboardInfo.java diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/LeaderboardInfo.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/LeaderboardInfo.java index 3d67c9a3122..1b4cae34c3c 100644 --- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/LeaderboardInfo.java +++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/LeaderboardInfo.java @@ -3,6 +3,7 @@ package com.sap.sailing.android.shared.data; public class LeaderboardInfo { public String name; + public String displayName; public String checkinDigest; public int rowId; public String serverUrl; diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/adapter/RegattaAdapter.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/adapter/RegattaAdapter.java index a7914b14e66..f3257d48ccf 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/adapter/RegattaAdapter.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/adapter/RegattaAdapter.java @@ -21,7 +21,7 @@ public class RegattaAdapter extends AbstractRegattaAdapter { public void bindView(View view, Context context, Cursor cursor) { TextView regattaName = ViewHelper.get(view,R.id.regattaName); if (regattaName != null) { - String regatteNameText = cursor.getString(cursor.getColumnIndex(AnalyticsContract.Leaderboard.LEADERBOARD_NAME)); + String regatteNameText = cursor.getString(cursor.getColumnIndex(AnalyticsContract.Leaderboard.LEADERBOARD_DISPLAY_NAME)); regattaName.setText(regatteNameText); } TextView regattaEvent = ViewHelper.get(view, R.id.regatta_event); diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java index ad434abf303..85caf5e6667 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java @@ -4,6 +4,8 @@ import android.content.ContentResolver; import android.net.Uri; import android.provider.BaseColumns; +import com.sap.sailing.android.tracking.app.provider.AnalyticsDatabase.Tables; + public class AnalyticsContract { interface CompetitorColumns { @@ -17,6 +19,7 @@ public class AnalyticsContract { interface LeaderboardColumns { String LEADERBOARD_NAME = "leaderboard_name"; + String LEADERBOARD_DISPLAY_NAME = "leaderboard_display_name"; String LEADERBOARD_CHECKIN_DIGEST = "leaderboard_checkin_digest"; } @@ -46,12 +49,6 @@ public class AnalyticsContract { public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); - public static final String PATH_COMPETITOR = "competitors"; - public static final String PATH_EVENT = "events"; - public static final String PATH_LEADERBOARD = "leaderboards"; - public static final String PATH_CHECKIN = "checkin_uris"; - public static final String PATH_MARK = "marks"; - public static class LeaderboardsEventsCompetitorsMarksJoined { public final static Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath("leaderboards_events_competitors_marks_joined") .build(); @@ -68,100 +65,47 @@ public class AnalyticsContract { } public static class Competitor implements CompetitorColumns, BaseColumns { - public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_COMPETITOR).build(); + public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(Tables.COMPETITORS).build(); public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.sap_sailing_analytics.competitor"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.sap_sailing_analytics.competitor"; - public static final String DEFAULT_SORT = CompetitorColumns.COMPETITOR_ID + " COLLATE NOCASE ASC"; - - public static Uri buildCompetitorUri(String competitorId) { - return CONTENT_URI.buildUpon().appendPath(competitorId).build(); - } - - public static Uri buildEventsDirUri(String competitorId) { - return CONTENT_URI.buildUpon().appendPath(competitorId).appendPath(PATH_EVENT).build(); - } - - public static String getCompetitorId(Uri uri) { - return uri.getPathSegments().get(1); - } } public static class Event implements EventColumns, BaseColumns { - public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_EVENT).build(); + public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(Tables.EVENTS).build(); public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.sap_sailing_analytics.event"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.sap_sailing_analytics.event"; - public static final String DEFAULT_SORT = EventColumns.EVENT_NAME + " COLLATE NOCASE ASC "; - - public static Uri buildEventUri(String eventId) { - return CONTENT_URI.buildUpon().appendPath(eventId).build(); - } - - public static Uri buildCompetitorsDirUri(String evevntId) { - return CONTENT_URI.buildUpon().appendPath(evevntId).appendPath(PATH_COMPETITOR).build(); - } - - public static String getEventId(Uri uri) { - return uri.getPathSegments().get(1); - } } public static class Leaderboard implements LeaderboardColumns { - public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_LEADERBOARD).build(); + public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(Tables.LEADERBOARDS).build(); public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.sap_sailing_analytics.leaderboard"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.sap_sailing_analytics.leaderboard"; - public static final String DEFAULT_SORT = BaseColumns._ID + " ASC "; - - public static Uri buildLeaderboardUri(String leaderboardId) { - return CONTENT_URI.buildUpon().appendPath(leaderboardId).build(); - } - - public static String getLeaderboardId(Uri uri) { - return uri.getPathSegments().get(1); - } } public static class Checkin implements CheckinColumns, BaseColumns { - public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_CHECKIN).build(); + public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(Tables.CHECKIN_URIS).build(); public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.sap_sailing_analytics.uri"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.sap_sailing_analytics.uri"; - public static final String DEFAULT_SORT = BaseColumns._ID + " ASC "; - - public static Uri builCheckInUri(String checkinUriId) { - return CONTENT_URI.buildUpon().appendPath(checkinUriId).build(); - } - - public static String getCheckinUriId(Uri uri) { - return uri.getPathSegments().get(1); - } } public static class Mark implements markColums, BaseColumns { - public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_MARK).build(); + public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(Tables.MARKS).build(); public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.sap_sailing_analytics.Mark"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.sap_sailing_analytics.Mark"; - public static final String DEFAULT_SORT = BaseColumns._ID + " ASC "; - - public static Uri buildMarkUri(String leaderboardId) { - return CONTENT_URI.buildUpon().appendPath(leaderboardId).build(); - } - - public static String getMarkId(Uri uri) { - return uri.getPathSegments().get(1); - } } private AnalyticsContract() { diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java index c578281325d..e26f6c0ed2a 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java @@ -6,6 +6,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns; import com.sap.sailing.android.shared.logging.ExLog; +import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Checkin; import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Competitor; import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.CompetitorColumns; import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Event; @@ -20,8 +21,7 @@ public class AnalyticsDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "sap_sailing_analytics.db"; - private static final int VER_2016_RELEASE_1 = 2; - private static final int CUR_DATABASE_VERSION = VER_2016_RELEASE_1; + private static final int DATABASE_VERSION = 3; private static final String createMarkTable = "CREATE TABLE " + Tables.MARKS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + AnalyticsContract.Mark.MARK_ID + " TEXT, " @@ -33,15 +33,16 @@ public class AnalyticsDatabase extends SQLiteOpenHelper { public interface Tables { String COMPETITORS = "competitors"; String EVENTS = "events"; - String EVENTS_COMPETITORS = "events_competitors"; String LEADERBOARDS = "leaderboards"; String CHECKIN_URIS = "checkin_uris"; String MARKS = "marks"; + String EVENTS_JOIN_LEADERBOARDS_JOIN_MARKS = Tables.LEADERBOARDS + " INNER JOIN " + Tables.EVENTS + " ON (" + Tables.LEADERBOARDS + "." + Leaderboard.LEADERBOARD_CHECKIN_DIGEST + " = " + Tables.EVENTS + "." + Event.EVENT_CHECKIN_DIGEST + ") " + " INNER JOIN " + Tables.MARKS + " ON (" + Tables.LEADERBOARDS + "." + Leaderboard.LEADERBOARD_CHECKIN_DIGEST + " = " + Tables.MARKS + "." + AnalyticsContract.Mark.MARK_CHECKIN_DIGEST + ") "; + String EVENTS_JOIN_LEADERBOARDS_JOIN_COMPETITORS = Tables.LEADERBOARDS + " INNER JOIN " + Tables.EVENTS + " ON (" + Tables.LEADERBOARDS + "." + Leaderboard.LEADERBOARD_CHECKIN_DIGEST + " = " + Tables.EVENTS + "." + Event.EVENT_CHECKIN_DIGEST + ") " + " INNER JOIN " + Tables.COMPETITORS + " ON (" @@ -52,7 +53,7 @@ public class AnalyticsDatabase extends SQLiteOpenHelper { + " ON (" + Tables.LEADERBOARDS + "." + Leaderboard.LEADERBOARD_CHECKIN_DIGEST + " = " + Tables.EVENTS + "." + Event.EVENT_CHECKIN_DIGEST + ") " + " INNER JOIN " + Tables.CHECKIN_URIS + " ON (" + Tables.LEADERBOARDS + "." + Leaderboard.LEADERBOARD_CHECKIN_DIGEST + " = " + Tables.CHECKIN_URIS + "." - + AnalyticsContract.Checkin.CHECKIN_URI_CHECKIN_DIGEST + ") " + + Checkin.CHECKIN_URI_CHECKIN_DIGEST + ") " + " LEFT OUTER JOIN " + Tables.COMPETITORS + " ON (" + Tables.LEADERBOARDS + "." + Leaderboard.LEADERBOARD_CHECKIN_DIGEST + " = " + Tables.COMPETITORS + "." + Competitor.COMPETITOR_CHECKIN_DIGEST + ") " @@ -62,7 +63,7 @@ public class AnalyticsDatabase extends SQLiteOpenHelper { } public AnalyticsDatabase(Context context) { - super(context, DATABASE_NAME, null, CUR_DATABASE_VERSION); + super(context, DATABASE_NAME, null, DATABASE_VERSION); mContext = context; } @@ -70,7 +71,8 @@ public class AnalyticsDatabase extends SQLiteOpenHelper { public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + Tables.LEADERBOARDS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + LeaderboardColumns.LEADERBOARD_CHECKIN_DIGEST + " TEXT, " - + LeaderboardColumns.LEADERBOARD_NAME + " TEXT );"); + + LeaderboardColumns.LEADERBOARD_NAME + " TEXT, " + + LeaderboardColumns.LEADERBOARD_DISPLAY_NAME + " TEXT);"); db.execSQL("CREATE TABLE " + Tables.CHECKIN_URIS + " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + CheckinColumns.CHECKIN_URI_CHECKIN_DIGEST + " TEXT, " @@ -96,9 +98,13 @@ public class AnalyticsDatabase extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { ExLog.i(mContext, TAG, "onUpgrade() from " + oldVersion + " to " + newVersion); - if (oldVersion == 1 && newVersion == 2) { + if (oldVersion < 2) { db.execSQL(createMarkTable); - db.execSQL("ALTER TABLE " + Tables.CHECKIN_URIS + " ADD COLUMN " + AnalyticsContract.Checkin.CHECKIN_TYPE + " INTEGER DEFAULT 0"); + db.execSQL("ALTER TABLE " + Tables.CHECKIN_URIS + " ADD COLUMN " + Checkin.CHECKIN_TYPE + " INTEGER DEFAULT 0"); + } + if (oldVersion < 3) { + db.execSQL("ALTER TABLE " + Tables.LEADERBOARDS + " ADD COLUMN " + Leaderboard.LEADERBOARD_DISPLAY_NAME + " TEXT"); + db.execSQL("UPDATE " + Tables.LEADERBOARDS + " SET " + Leaderboard.LEADERBOARD_DISPLAY_NAME + " = " + Leaderboard.LEADERBOARD_NAME); } } diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java index 9775ebb8150..3b1f4635b3e 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java @@ -3,6 +3,7 @@ package com.sap.sailing.android.tracking.app.provider; import java.util.Arrays; import android.content.ContentProvider; +import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; @@ -11,6 +12,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.provider.BaseColumns; +import android.util.Log; import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.util.SelectionBuilder; @@ -39,9 +41,6 @@ public class AnalyticsProvider extends ContentProvider { private static final int LEADERBOARD = 300; private static final int LEADERBOARD_ID = 301; - private static final int MESSAGE = 400; - private static final int MESSAGE_ID = 401; - private static final int CHECKIN_URI = 500; private static final int CHECKIN_URI_ID = 501; @@ -59,20 +58,17 @@ public class AnalyticsProvider extends ContentProvider { final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); final String authority = AnalyticsContract.CONTENT_AUTHORITY; - matcher.addURI(authority, "competitors", COMPETITOR); - matcher.addURI(authority, "competitors/*", COMPETITOR_ID); + matcher.addURI(authority, Tables.COMPETITORS, COMPETITOR); + matcher.addURI(authority, Tables.COMPETITORS + "/*", COMPETITOR_ID); - matcher.addURI(authority, "leaderboards", LEADERBOARD); - matcher.addURI(authority, "leaderboards/*", LEADERBOARD_ID); + matcher.addURI(authority, Tables.LEADERBOARDS, LEADERBOARD); + matcher.addURI(authority, Tables.LEADERBOARDS + "/*", LEADERBOARD_ID); - matcher.addURI(authority, "checkin_uris", CHECKIN_URI); - matcher.addURI(authority, "checkin_uris/*", CHECKIN_URI_ID); + matcher.addURI(authority, Tables.CHECKIN_URIS, CHECKIN_URI); + matcher.addURI(authority, Tables.CHECKIN_URIS + "/*", CHECKIN_URI_ID); - matcher.addURI(authority, "events", EVENT); - matcher.addURI(authority, "events/*", EVENT_ID); - - matcher.addURI(authority, "messages", MESSAGE); - matcher.addURI(authority, "messages/#", MESSAGE_ID); + matcher.addURI(authority, Tables.EVENTS, EVENT); + matcher.addURI(authority, Tables.EVENTS + "/*", EVENT_ID); matcher.addURI(authority, "event_leaderboard_competitor_joined", EVENT_LEADERBOARD_COMPETITOR_JOINED); matcher.addURI(authority, "event_leaderboard_mark_joined", EVENT_LEADERBOARD_MARK_JOINED); @@ -81,8 +77,8 @@ public class AnalyticsProvider extends ContentProvider { matcher.addURI(authority, "leaderboards_events_competitors_marks_joined", LEADERBOARDS_EVENTS_COMPETITORS_MARKS_JOINED); - matcher.addURI(authority, "marks", MARK); - matcher.addURI(authority, "marks/*", MARK_ID); + matcher.addURI(authority, Tables.MARKS, MARK); + matcher.addURI(authority, Tables.MARKS + "/*", MARK_ID); return matcher; } @@ -93,56 +89,48 @@ public class AnalyticsProvider extends ContentProvider { return true; } - // private void deleteDatabase() { - // Context context = getContext(); - // mOpenHelper.close(); - // AnalyticsDatabase.deleteDatabase(context); - // mOpenHelper = new AnalyticsDatabase(context); - // } - @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - if (BuildConfig.DEBUG && AppPreferences.getPrintDatabaseOperationDebugMessages()) { - String message = "query: uri=" + uri + " projection=" + Arrays.toString(projection) + " selection=[" + selection + "] args=" + Arrays - .toString(selectionArgs) + " order=[" + sortOrder + "]"; - ExLog.i(getContext(), TAG, message); + if (BuildConfig.DEBUG) { + ExLog.i(getContext(), TAG, + "query() called with: uri = [" + uri + "], projection = [" + Arrays.toString(projection) + "], selection = [" + + selection + "], selectionArgs = [" + Arrays.toString(selectionArgs) + "], sortOrder = [" + sortOrder + "]"); } final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - Cursor cursor; - + final SQLiteQueryBuilder builder = new SQLiteQueryBuilder(); + String table = null; switch (sUriMatcher.match(uri)) { - case EVENT_LEADERBOARD_MARK_JOINED: - SQLiteQueryBuilder mqb = new SQLiteQueryBuilder(); - mqb.setTables(Tables.EVENTS_JOIN_LEADERBOARDS_JOIN_MARKS); - cursor = mqb.query(db, projection, selection, selectionArgs, null, null, sortOrder); - return cursor; + table = Tables.EVENTS_JOIN_LEADERBOARDS_JOIN_MARKS; + break; + case EVENT_LEADERBOARD_COMPETITOR_JOINED: - SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - qb.setTables(Tables.EVENTS_JOIN_LEADERBOARDS_JOIN_COMPETITORS); - cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); - return cursor; + table = Tables.EVENTS_JOIN_LEADERBOARDS_JOIN_COMPETITORS; + break; case LEADERBOARDS_EVENTS_COMPETITORS_MARKS_JOINED: - SQLiteQueryBuilder el = new SQLiteQueryBuilder(); - el.setTables(Tables.LEADERBOARDS_JOIN_EVENTS_JOIN_COMPETITORS_JOIN_MARKS); - cursor = el.query(db, projection, selection, selectionArgs, null, null, sortOrder); - return cursor; + table = Tables.LEADERBOARDS_JOIN_EVENTS_JOIN_COMPETITORS_JOIN_MARKS; + break; default: - final SelectionBuilder builder = buildExpandedSelection(uri); - - cursor = builder.where(selection, selectionArgs).query(db, false, projection, sortOrder, null); - - Context context = getContext(); - if (context != null) { - cursor.setNotificationUri(context.getContentResolver(), uri); - } - - return cursor; + // np-op } + + Cursor cursor; + if (table != null) { + builder.setTables(table); + cursor = builder.query(db, projection, selection, selectionArgs, null, null, sortOrder); + } else { + final SelectionBuilder selectionBuilder = buildExpandedSelection(uri); + cursor = selectionBuilder.where(selection, selectionArgs).query(db, false, projection, sortOrder, null); + } + Context context = getContext(); + if (context != null) { + cursor.setNotificationUri(context.getContentResolver(), uri); + } + return cursor; } @Override @@ -165,14 +153,19 @@ public class AnalyticsProvider extends ContentProvider { case LEADERBOARD_ID: return Leaderboard.CONTENT_ITEM_TYPE; + case CHECKIN_URI: return Checkin.CONTENT_TYPE; + case CHECKIN_URI_ID: return Checkin.CONTENT_ITEM_TYPE; + case MARK: return AnalyticsContract.Mark.CONTENT_TYPE; + case MARK_ID: return AnalyticsContract.Mark.CONTENT_ITEM_TYPE; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -180,93 +173,90 @@ public class AnalyticsProvider extends ContentProvider { @Override public Uri insert(Uri uri, ContentValues values) { - if (BuildConfig.DEBUG && AppPreferences.getPrintDatabaseOperationDebugMessages()) { + if (BuildConfig.DEBUG) { String message = "insert: uri=" + uri + " values=[" + values.toString() + "]"; ExLog.i(getContext(), TAG, message); } final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - + String table; switch (sUriMatcher.match(uri)) { case COMPETITOR: - long competitorId = db.insertOrThrow(Tables.COMPETITORS, null, values); - notifyChange(uri); - return Competitor.buildCompetitorUri(String.valueOf(competitorId)); + table = Tables.COMPETITORS; + break; case EVENT: - long eventId = db.insertOrThrow(Tables.EVENTS, null, values); - notifyChange(uri); - return Event.buildEventUri(String.valueOf(eventId)); + table = Tables.EVENTS; + break; case LEADERBOARD: - long leaderboardId = db.insertOrThrow(Tables.LEADERBOARDS, null, values); - notifyChange(uri); - return Leaderboard.buildLeaderboardUri(String.valueOf(leaderboardId)); + table = Tables.LEADERBOARDS; + break; case CHECKIN_URI: - long checkinUriID = db.insertOrThrow(Tables.CHECKIN_URIS, null, values); - notifyChange(uri); - return Checkin.builCheckInUri(String.valueOf(checkinUriID)); + table = Tables.CHECKIN_URIS; + break; case MARK: - long markUriID = db.insertOrThrow(Tables.MARKS, null, values); - notifyChange(uri); - return AnalyticsContract.Mark.buildMarkUri(String.valueOf(markUriID)); + table = Tables.MARKS; + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } + + long id = db.insertOrThrow(table, null, values); + notifyChange(uri); + return uri.buildUpon().appendPath(String.valueOf(id)).build(); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { - if (BuildConfig.DEBUG && AppPreferences.getPrintDatabaseOperationDebugMessages()) { - String message = "delete: uri=" + uri + " selection=[" + selection + "] args=" + Arrays.toString(selectionArgs); - ExLog.i(getContext(), TAG, message); + if (BuildConfig.DEBUG) { + ExLog.i(getContext(), TAG, "delete() called with: uri = [" + uri + "], selection = [" + selection + + "], selectionArgs = [" + Arrays.toString(selectionArgs) + "]"); } + String table; final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); switch (sUriMatcher.match(uri)) { - case COMPETITOR: - int numCompetitorRowsDeleted = db.delete(Tables.COMPETITORS, selection, selectionArgs); - notifyChange(uri); - return numCompetitorRowsDeleted; + table = Tables.COMPETITORS; + break; case EVENT: - int numEventRowsDeleted = db.delete(Tables.EVENTS, selection, selectionArgs); - notifyChange(uri); - return numEventRowsDeleted; + table = Tables.EVENTS; + break; case LEADERBOARD: - int numLeaderboardRowsDeleted = db.delete(Tables.LEADERBOARDS, selection, selectionArgs); - notifyChange(uri); - return numLeaderboardRowsDeleted; + table = Tables.LEADERBOARDS; + break; + case CHECKIN_URI: - int numCheckinUriRowsDeleted = db.delete(Tables.CHECKIN_URIS, selection, selectionArgs); - notifyChange(uri); - return numCheckinUriRowsDeleted; + table = Tables.CHECKIN_URIS; + break; + case MARK: - int numMarkRowsDeleted = db.delete(Tables.MARKS, selection, selectionArgs); - notifyChange(uri); - return numMarkRowsDeleted; + table = Tables.MARKS; + break; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } + + int rowsDeleted = db.delete(table, selection, selectionArgs); + notifyChange(uri); + return rowsDeleted; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - if (BuildConfig.DEBUG && AppPreferences.getPrintDatabaseOperationDebugMessages()) { - String message = "update: uri=" + uri + " values=[" + values == null ? - "null" : - values.toString() + "] selection=[" + selection + "]" + " args=" + Arrays.toString(selectionArgs); - ExLog.i(getContext(), TAG, message); + if (BuildConfig.DEBUG) { + ExLog.i(getContext(), TAG, "update() called with: uri = [" + uri + "], values = [" + values + "], selection = [" + selection + "], selectionArgs = [" + + Arrays.toString(selectionArgs) + "]"); } - // final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - switch (sUriMatcher.match(uri)) { default: throw new UnsupportedOperationException("Unknown uri: " + uri); @@ -274,7 +264,10 @@ public class AnalyticsProvider extends ContentProvider { } private void notifyChange(Uri uri) { - getContext().getContentResolver().notifyChange(uri, null); + ContentResolver cr = getContext().getContentResolver(); + if (cr != null) { + cr.notifyChange(uri, null); + } } private SelectionBuilder buildExpandedSelection(Uri uri) { @@ -285,31 +278,35 @@ public class AnalyticsProvider extends ContentProvider { return builder.table(Tables.COMPETITORS); case COMPETITOR_ID: - final String competitor_id = Competitor.getCompetitorId(uri); + final String competitor_id = uri.getLastPathSegment(); return builder.table(Tables.COMPETITORS).where(Competitor.COMPETITOR_ID + " = ?", competitor_id); case LEADERBOARD: return builder.table(Tables.LEADERBOARDS); case LEADERBOARD_ID: - final String leaderboard_id = Leaderboard.getLeaderboardId(uri); + final String leaderboard_id = uri.getLastPathSegment(); return builder.table(Tables.LEADERBOARDS).where(BaseColumns._ID + " = ?", leaderboard_id); case EVENT: return builder.table(Tables.EVENTS); case EVENT_ID: - final String event_id = Event.getEventId(uri); + final String event_id = uri.getLastPathSegment(); return builder.table(Tables.EVENTS).where(Event.EVENT_ID + " = ?", event_id); + case CHECKIN_URI: return builder.table(Tables.CHECKIN_URIS); + case CHECKIN_URI_ID: - final String checkinUriId = Checkin.getCheckinUriId(uri); + final String checkinUriId = uri.getLastPathSegment(); return builder.table(Tables.CHECKIN_URIS).where(BaseColumns._ID + " = ?", checkinUriId); + case MARK: return builder.table(Tables.MARKS); + case MARK_ID: - final String mark_id = AnalyticsContract.Mark.getMarkId(uri); + final String mark_id = uri.getLastPathSegment(); return builder.table(Tables.MARKS).where(BaseColumns._ID + " = ?", mark_id); default: diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java index 8e9771f0e9b..52af17bc9a6 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java @@ -44,6 +44,7 @@ import com.sap.sailing.android.tracking.app.BuildConfig; import com.sap.sailing.android.tracking.app.R; import com.sap.sailing.android.tracking.app.adapter.RegattaAdapter; import com.sap.sailing.android.tracking.app.provider.AnalyticsContract; +import com.sap.sailing.android.tracking.app.provider.AnalyticsDatabase; import com.sap.sailing.android.tracking.app.ui.activities.BuoyActivity; import com.sap.sailing.android.tracking.app.ui.activities.RegattaActivity; import com.sap.sailing.android.tracking.app.ui.activities.StartActivity; @@ -268,14 +269,14 @@ public class HomeFragment extends AbstractHomeFragment implements LoaderCallback public Loader onCreateLoader(int loaderId, Bundle bundle) { switch (loaderId) { case REGATTA_LOADER: - String[] projection = new String[] { AnalyticsContract.PATH_EVENT + "." + AnalyticsContract.Event.EVENT_CHECKIN_DIGEST, - AnalyticsContract.PATH_EVENT + "." + AnalyticsContract.Event._ID, - AnalyticsContract.PATH_EVENT + "." + AnalyticsContract.Event.EVENT_NAME, - AnalyticsContract.PATH_EVENT + "." + AnalyticsContract.Event.EVENT_SERVER, - AnalyticsContract.PATH_LEADERBOARD + "." + AnalyticsContract.Leaderboard.LEADERBOARD_NAME, - AnalyticsContract.PATH_COMPETITOR + "." + AnalyticsContract.Competitor.COMPETITOR_DISPLAY_NAME, - AnalyticsContract.PATH_MARK + "." + AnalyticsContract.Mark.MARK_NAME, - AnalyticsContract.PATH_CHECKIN + "." + AnalyticsContract.Checkin.CHECKIN_TYPE}; + String[] projection = new String[] { AnalyticsDatabase.Tables.EVENTS + "." + AnalyticsContract.Event.EVENT_CHECKIN_DIGEST, + AnalyticsDatabase.Tables.EVENTS + "." + AnalyticsContract.Event._ID, + AnalyticsDatabase.Tables.EVENTS + "." + AnalyticsContract.Event.EVENT_NAME, + AnalyticsDatabase.Tables.EVENTS + "." + AnalyticsContract.Event.EVENT_SERVER, + AnalyticsDatabase.Tables.LEADERBOARDS + "." + AnalyticsContract.Leaderboard.LEADERBOARD_DISPLAY_NAME, + AnalyticsDatabase.Tables.COMPETITORS + "." + AnalyticsContract.Competitor.COMPETITOR_DISPLAY_NAME, + AnalyticsDatabase.Tables.MARKS + "." + AnalyticsContract.Mark.MARK_NAME, + AnalyticsDatabase.Tables.CHECKIN_URIS + "." + AnalyticsContract.Checkin.CHECKIN_TYPE}; return new CursorLoader(getActivity(), AnalyticsContract.LeaderboardsEventsCompetitorsMarksJoined.CONTENT_URI, projection, null, null, null); default: diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/AppPreferences.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/AppPreferences.java index 73ed94a3232..2c5b1888014 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/AppPreferences.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/AppPreferences.java @@ -143,10 +143,6 @@ public class AppPreferences extends BaseAppPreferences { return preferences.getString(context.getString(R.string.preference_tracker_is_tracking_checkin_digest), null); } - public static boolean getPrintDatabaseOperationDebugMessages() { - return false; - } - public void setMessageResendIntervalInMillis(int intervalInMillis) { preferences.edit().putInt(context.getString(R.string.preference_messageResendIntervalMillis_key), intervalInMillis).commit(); } diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/CheckinManager.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/CheckinManager.java index 18b4f09a7c7..68954031d9e 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/CheckinManager.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/CheckinManager.java @@ -3,6 +3,7 @@ package com.sap.sailing.android.tracking.app.utils; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLDecoder; import java.net.URLEncoder; import java.security.NoSuchAlgorithmException; import java.util.Set; @@ -56,6 +57,7 @@ public class CheckinManager { private BaseCheckinData checkinData; private CheckinDataActivity activity; private AppPreferences prefs; + private UrlData urlData; private String url; private boolean update; @@ -70,7 +72,7 @@ public class CheckinManager { Uri uri = Uri.parse(url); String scheme = uri.getScheme(); - final UrlData urlData = extractRequestParametersFromUri(uri, scheme); + urlData = extractRequestParametersFromUri(uri, scheme); if (urlData == null) { setCheckinData(null); return; @@ -80,7 +82,7 @@ public class CheckinManager { try { HttpGetRequest getLeaderboardRequest = new HttpGetRequest(new URL(urlData.leaderboardUrl), activity); - getLeaderBoardFromServer(urlData, getLeaderboardRequest); + getLeaderBoardFromServer(getLeaderboardRequest); } catch (MalformedURLException e) { ExLog.e(activity, TAG, "Error: Failed to perform checking due to a MalformedURLException: " + e.getMessage()); @@ -111,13 +113,15 @@ public class CheckinManager { ExLog.e(activity, TAG, "Neither mark nor competitor checkin"); exception = new Exception(); } - urlData.uriStr = uri.toString(); - urlData.checkinURLStr = urlData.hostWithPort + prefs.getServerCheckinPath().replace("{leaderboard-name}", leaderboardNameFromQR); - urlData.eventId = uri.getQueryParameter(DeviceMappingConstants.URL_EVENT_ID); - urlData.leaderboardName = leaderboardNameFromQR; - urlData.deviceUuid = new SmartphoneUUIDIdentifierImpl(UUID.fromString(UniqueDeviceUuid.getUniqueId(activity))); - urlData.eventUrl = urlData.hostWithPort + prefs.getServerEventPath(urlData.eventId); - urlData.leaderboardUrl = urlData.hostWithPort + prefs.getServerLeaderboardPath(urlData.leaderboardName); + if (urlData != null) { + urlData.uriStr = uri.toString(); + urlData.checkinURLStr = urlData.hostWithPort + prefs.getServerCheckinPath().replace("{leaderboard-name}", leaderboardNameFromQR); + urlData.eventId = uri.getQueryParameter(DeviceMappingConstants.URL_EVENT_ID); + urlData.leaderboardName = leaderboardNameFromQR; + urlData.deviceUuid = new SmartphoneUUIDIdentifierImpl(UUID.fromString(UniqueDeviceUuid.getUniqueId(activity))); + urlData.eventUrl = urlData.hostWithPort + prefs.getServerEventPath(urlData.eventId); + urlData.leaderboardUrl = urlData.hostWithPort + prefs.getServerLeaderboardPath(urlData.leaderboardName); + } } catch (UnsupportedEncodingException e) { ExLog.e(activity, TAG, "Failed to encode leaderboard name: " + e.getMessage()); @@ -134,25 +138,25 @@ public class CheckinManager { return urlData; } - private void getLeaderBoardFromServer(final UrlData urlData, HttpGetRequest getLeaderboardRequest) { + private void getLeaderBoardFromServer(HttpGetRequest getLeaderboardRequest) { NetworkHelper.getInstance(activity) .executeHttpJsonRequestAsync(getLeaderboardRequest, new NetworkHelper.NetworkHelperSuccessListener() { @Override public void performAction(JSONObject response) { - try { - // Check if call to leaderboard returned valid response - response.getString("name"); + urlData.leaderboardDisplayName = response.getString("displayName"); } catch (JSONException e) { - ExLog.e(activity, TAG, "Error getting data from call on URL: " + urlData.leaderboardUrl + ", Error: " + e.getMessage()); - handleApiError(); - return; + try { + urlData.leaderboardDisplayName = response.getString("name"); + } catch (JSONException ex) { + urlData.leaderboardDisplayName = urlData.leaderboardName; + } } HttpGetRequest getEventRequest; try { getEventRequest = new HttpGetRequest(new URL(urlData.eventUrl), activity); - getEventFromServer(getEventRequest, urlData); + getEventFromServer(getEventRequest); } catch (MalformedURLException e1) { ExLog.e(activity, TAG, "Error: Failed to perform checking due to a MalformedURLException: " + e1.getMessage()); handleApiError(); @@ -168,7 +172,7 @@ public class CheckinManager { }); } - private void getEventFromServer(HttpGetRequest getEventRequest, final UrlData urlData) { + private void getEventFromServer(HttpGetRequest getEventRequest) { NetworkHelper.getInstance(activity).executeHttpJsonRequestAsync(getEventRequest, new NetworkHelper.NetworkHelperSuccessListener() { @Override diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/DatabaseHelper.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/DatabaseHelper.java index 0a3bdda5c76..7712315c628 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/DatabaseHelper.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/DatabaseHelper.java @@ -60,45 +60,6 @@ public class DatabaseHelper { return checkinUrls; } - public long getEventRowIdForCheckinDigest(Context context, String checkinDigest) { - int result = 0; - - ContentResolver cr = context.getContentResolver(); - Cursor cursor = cr.query(Event.CONTENT_URI, null, Event.EVENT_CHECKIN_DIGEST + " = ?", - new String[] { checkinDigest }, null); - if (cursor != null) { - cursor.moveToFirst(); - result = cursor.getInt(cursor.getColumnIndex(BaseColumns._ID)); - cursor.close(); - } - return result; - } - - public EventInfo getEventInfoWithLeaderboardAndCompetitor(Context context, String checkinDigest) { - EventInfo result = new EventInfo(); - - ContentResolver cr = context.getContentResolver(); - String projectionStr = AnalyticsDatabase.Tables.EVENTS + "." + Event._ID + "," - + AnalyticsDatabase.Tables.LEADERBOARDS + "." + Leaderboard.LEADERBOARD_NAME + "," - + AnalyticsDatabase.Tables.EVENTS + "." + Event.EVENT_ID + "," - + AnalyticsDatabase.Tables.EVENTS + "." + Event.EVENT_NAME + "," - + AnalyticsDatabase.Tables.COMPETITORS + "." + Competitor.COMPETITOR_ID; - String[] projection = projectionStr.split(","); - Cursor cursor = cr.query(EventLeaderboardCompetitorJoined.CONTENT_URI, projection, - AnalyticsDatabase.Tables.EVENTS + "." + Event.EVENT_CHECKIN_DIGEST + " = ?", new String[] { checkinDigest }, null); - if (cursor != null) { - if (cursor.moveToFirst()) { - result.name = cursor.getString(cursor.getColumnIndex(Event.EVENT_NAME)); - result.leaderboardName = cursor.getString(cursor.getColumnIndex(Leaderboard.LEADERBOARD_NAME)); - result.competitorId = cursor.getString(cursor.getColumnIndex(Competitor.COMPETITOR_ID)); - result.id = cursor.getString(cursor.getColumnIndex(Event.EVENT_ID)); - } - - cursor.close(); - } - return result; - } - public EventInfo getEventInfo(Context context, String checkinDigest) { EventInfo event = new EventInfo(); event.checkinDigest = checkinDigest; @@ -145,15 +106,16 @@ public class DatabaseHelper { LeaderboardInfo leaderboard = new LeaderboardInfo(); leaderboard.checkinDigest = checkinDigest; - Cursor lc = context.getContentResolver().query(Leaderboard.CONTENT_URI, null, + Cursor cursor = context.getContentResolver().query(Leaderboard.CONTENT_URI, null, Leaderboard.LEADERBOARD_CHECKIN_DIGEST + " = ?", new String[] { checkinDigest }, null); - if (lc != null) { - if (lc.moveToFirst()) { - leaderboard.rowId = lc.getInt(lc.getColumnIndex(BaseColumns._ID)); - leaderboard.name = lc.getString(lc.getColumnIndex(Leaderboard.LEADERBOARD_NAME)); + if (cursor != null) { + if (cursor.moveToFirst()) { + leaderboard.rowId = cursor.getInt(cursor.getColumnIndex(BaseColumns._ID)); + leaderboard.name = cursor.getString(cursor.getColumnIndex(Leaderboard.LEADERBOARD_NAME)); + leaderboard.displayName = cursor.getString(cursor.getColumnIndex(Leaderboard.LEADERBOARD_DISPLAY_NAME)); } - lc.close(); + cursor.close(); } return leaderboard; @@ -229,17 +191,15 @@ public class DatabaseHelper { ArrayList opList = new ArrayList<>(); // competitor + ContentValues cv = new ContentValues(); + cv.put(Competitor.COMPETITOR_COUNTRY_CODE, competitor.countryCode); + cv.put(Competitor.COMPETITOR_DISPLAY_NAME, competitor.name); + cv.put(Competitor.COMPETITOR_ID, competitor.id); + cv.put(Competitor.COMPETITOR_NATIONALITY, competitor.nationality); + cv.put(Competitor.COMPETITOR_SAIL_ID, competitor.sailId); + cv.put(Competitor.COMPETITOR_CHECKIN_DIGEST, competitor.checkinDigest); - ContentValues ccv = new ContentValues(); - - ccv.put(Competitor.COMPETITOR_COUNTRY_CODE, competitor.countryCode); - ccv.put(Competitor.COMPETITOR_DISPLAY_NAME, competitor.name); - ccv.put(Competitor.COMPETITOR_ID, competitor.id); - ccv.put(Competitor.COMPETITOR_NATIONALITY, competitor.nationality); - ccv.put(Competitor.COMPETITOR_SAIL_ID, competitor.sailId); - ccv.put(Competitor.COMPETITOR_CHECKIN_DIGEST, competitor.checkinDigest); - - opList.add(ContentProviderOperation.newInsert(Competitor.CONTENT_URI).withValues(ccv).build()); + opList.add(ContentProviderOperation.newInsert(Competitor.CONTENT_URI).withValues(cv).build()); storeBasicInformation(leaderboard, event, checkinURL, opList, contentResolver); try { @@ -255,11 +215,11 @@ public class DatabaseHelper { // Store Mark information ContentResolver contentResolver = context.getContentResolver(); ArrayList opList = new ArrayList<>(); - ContentValues markValues = new ContentValues(); - markValues.put(AnalyticsContract.Mark.MARK_ID, mark.getId().toString()); - markValues.put(AnalyticsContract.Mark.MARK_NAME, mark.getName()); - markValues.put(AnalyticsContract.Mark.MARK_CHECKIN_DIGEST, checkinURL.checkinDigest); - opList.add(ContentProviderOperation.newInsert(AnalyticsContract.Mark.CONTENT_URI).withValues(markValues).build()); + ContentValues cv = new ContentValues(); + cv.put(AnalyticsContract.Mark.MARK_ID, mark.getId().toString()); + cv.put(AnalyticsContract.Mark.MARK_NAME, mark.getName()); + cv.put(AnalyticsContract.Mark.MARK_CHECKIN_DIGEST, checkinURL.checkinDigest); + opList.add(ContentProviderOperation.newInsert(AnalyticsContract.Mark.CONTENT_URI).withValues(cv).build()); storeBasicInformation(leaderboard, event, checkinURL, opList, contentResolver); @@ -274,34 +234,31 @@ public class DatabaseHelper { ArrayList opList, ContentResolver contentResolver) { // inserting leaderboard first - - ContentValues clv = new ContentValues(); - clv.put(Leaderboard.LEADERBOARD_NAME, leaderboard.name); - clv.put(Leaderboard.LEADERBOARD_CHECKIN_DIGEST, leaderboard.checkinDigest); - contentResolver.insert(Leaderboard.CONTENT_URI, clv); + ContentValues cv = new ContentValues(); + cv.put(Leaderboard.LEADERBOARD_NAME, leaderboard.name); + cv.put(Leaderboard.LEADERBOARD_DISPLAY_NAME, leaderboard.displayName); + cv.put(Leaderboard.LEADERBOARD_CHECKIN_DIGEST, leaderboard.checkinDigest); + contentResolver.insert(Leaderboard.CONTENT_URI, cv); // now insert event + cv.clear(); + cv.put(Event.EVENT_ID, event.id); + cv.put(Event.EVENT_NAME, event.name); + cv.put(Event.EVENT_DATE_START, event.startMillis); + cv.put(Event.EVENT_DATE_END, event.endMillis); + cv.put(Event.EVENT_SERVER, event.server); + cv.put(Event.EVENT_IMAGE_URL, event.imageUrl); + cv.put(Event.EVENT_CHECKIN_DIGEST, event.checkinDigest); - ContentValues cev = new ContentValues(); - cev.put(Event.EVENT_ID, event.id); - cev.put(Event.EVENT_NAME, event.name); - cev.put(Event.EVENT_DATE_START, event.startMillis); - cev.put(Event.EVENT_DATE_END, event.endMillis); - cev.put(Event.EVENT_SERVER, event.server); - cev.put(Event.EVENT_IMAGE_URL, event.imageUrl); - cev.put(Event.EVENT_CHECKIN_DIGEST, event.checkinDigest); - - opList.add(ContentProviderOperation.newInsert(Event.CONTENT_URI).withValues(cev).build()); + opList.add(ContentProviderOperation.newInsert(Event.CONTENT_URI).withValues(cv).build()); // checkin url + cv.clear(); + cv.put(Checkin.CHECKIN_URI_VALUE, checkinURL.urlString); + cv.put(Checkin.CHECKIN_URI_CHECKIN_DIGEST, checkinURL.checkinDigest); + cv.put(Checkin.CHECKIN_TYPE, checkinURL.type); - ContentValues ccuv = new ContentValues(); - - ccuv.put(Checkin.CHECKIN_URI_VALUE, checkinURL.urlString); - ccuv.put(Checkin.CHECKIN_URI_CHECKIN_DIGEST, checkinURL.checkinDigest); - ccuv.put(Checkin.CHECKIN_TYPE, checkinURL.type); - - opList.add(ContentProviderOperation.newInsert(Checkin.CONTENT_URI).withValues(ccuv).build()); + opList.add(ContentProviderOperation.newInsert(Checkin.CONTENT_URI).withValues(cv).build()); } /** diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/SqlDebugHelper.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/SqlDebugHelper.java deleted file mode 100644 index 6e55bba4ee0..00000000000 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/utils/SqlDebugHelper.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.sap.sailing.android.tracking.app.utils; - -import android.content.ContentResolver; -import android.content.Context; -import android.database.Cursor; -import android.provider.BaseColumns; - -import com.sap.sailing.android.shared.logging.ExLog; -import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Competitor; -import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Event; -import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Leaderboard; - -public class SqlDebugHelper { - - static final public String TAG = SqlDebugHelper.class.getName(); - - public static void dumpAllTablesToConsole(Context context) { - ExLog.w(context, TAG, "--- PRINT ALL SQL"); - ExLog.w(context, TAG, "+++ LEADERBOARDS +++"); - - ContentResolver cr = context.getContentResolver(); - Cursor c1 = cr.query(Leaderboard.CONTENT_URI, null, null, null, null); - - while (c1.moveToNext()) { - StringBuffer sb = new StringBuffer(); - sb.append("_ID: " + c1.getString(c1.getColumnIndex(BaseColumns._ID)) + ", "); - sb.append("NAME: " + c1.getString(c1.getColumnIndex(Leaderboard.LEADERBOARD_NAME)) + "\n"); - sb.append("DIGEST: " + c1.getString(c1.getColumnIndex(Leaderboard.LEADERBOARD_CHECKIN_DIGEST)) + "\n"); - ExLog.w(context, TAG, "Leaderboard: " + sb.toString()); - } - - ExLog.w(context, TAG, "+++ EVENTS +++"); - - c1.close(); - - Cursor c2 = cr.query(Event.CONTENT_URI, null, null, null, null); - - while (c2.moveToNext()) { - StringBuffer sb = new StringBuffer(); - sb.append("_ID: " + c2.getString(c2.getColumnIndex(BaseColumns._ID)) + ", "); - sb.append("ID: " + c2.getString(c2.getColumnIndex(Event.EVENT_ID)) + ", "); - sb.append("NAME: " + c2.getString(c2.getColumnIndex(Event.EVENT_NAME)) + ", "); - sb.append("DATE START: " + c2.getString(c2.getColumnIndex(Event.EVENT_DATE_START)) + ", "); - sb.append("DATE END: " + c2.getString(c2.getColumnIndex(Event.EVENT_DATE_END)) + ", "); - sb.append("IMAGE-URL: " + c2.getString(c2.getColumnIndex(Event.EVENT_IMAGE_URL)) + ", "); - sb.append("SERVER: " + c2.getString(c2.getColumnIndex(Event.EVENT_SERVER)) + "\n"); - sb.append("DIGEST: " + c2.getString(c2.getColumnIndex(Event.EVENT_CHECKIN_DIGEST)) + "\n"); - - ExLog.w(context, TAG, "Event: " + sb.toString()); - } - - ExLog.w(context, TAG, "+++ COMPETITORS +++"); - - c2.close(); - - Cursor c3 = cr.query(Competitor.CONTENT_URI, null, null, null, null); - - while (c3.moveToNext()) { - StringBuffer sb = new StringBuffer(); - sb.append("_ID: " + c3.getString(c3.getColumnIndex(BaseColumns._ID)) + ", "); - sb.append("ID: " + c3.getString(c3.getColumnIndex(Competitor.COMPETITOR_ID)) + ", "); - sb.append("DISPLAY NAME: " + c3.getString(c3.getColumnIndex(Competitor.COMPETITOR_DISPLAY_NAME)) + ", "); - sb.append("NATIONALITY: " + c3.getString(c3.getColumnIndex(Competitor.COMPETITOR_NATIONALITY)) + ", "); - sb.append("COUNTRY CODE: " + c3.getString(c3.getColumnIndex(Competitor.COMPETITOR_COUNTRY_CODE)) + ", "); - sb.append("SAIL-ID: " + c3.getString(c3.getColumnIndex(Competitor.COMPETITOR_SAIL_ID)) + "\n"); - sb.append("DIGEST: " + c3.getString(c3.getColumnIndex(Competitor.COMPETITOR_CHECKIN_DIGEST)) + "\n"); - - ExLog.w(context, TAG, "Competitor: " + sb.toString()); - } - - c3.close(); - - ExLog.w(context, TAG, "--- END OF SQL PRINTOUT"); - } -} diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/CheckinData.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/CheckinData.java index 6b256f110fa..8819d216454 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/CheckinData.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/CheckinData.java @@ -12,6 +12,7 @@ import android.net.Uri; public abstract class CheckinData extends BaseCheckinData { private String leaderboardName; + private String leaderboardDisplayName; private String eventId; private String eventName; private String eventStartDateStr; @@ -26,6 +27,7 @@ public abstract class CheckinData extends BaseCheckinData { public CheckinData(UrlData data) { leaderboardName = Uri.decode(data.leaderboardName); + leaderboardDisplayName = data.leaderboardDisplayName; deviceUid = data.deviceUuid.getStringRepresentation(); eventId = data.eventId; eventName = data.eventName; @@ -64,6 +66,7 @@ public abstract class CheckinData extends BaseCheckinData { public LeaderboardInfo getLeaderboard() { LeaderboardInfo leaderboard = new LeaderboardInfo(); leaderboard.name = leaderboardName; + leaderboard.displayName = leaderboardDisplayName; leaderboard.checkinDigest = checkinDigest; return leaderboard; } diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/LeaderboardInfo.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/LeaderboardInfo.java deleted file mode 100644 index 7cbb9e3d4e3..00000000000 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/LeaderboardInfo.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sap.sailing.android.tracking.app.valueobjects; - -public class LeaderboardInfo { - - public String name; - public String checkinDigest; - public int rowId; -} diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/UrlData.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/UrlData.java index eb004517aee..6ca45147270 100644 --- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/UrlData.java +++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/valueobjects/UrlData.java @@ -10,6 +10,7 @@ public abstract class UrlData { public String checkinURLStr; public String eventId; public String leaderboardName; + public String leaderboardDisplayName; public DeviceIdentifier deviceUuid; public String eventUrl; public String leaderboardUrl; From 295f35e23f253facc9dd5f6c93913e6da6816e9c Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Mon, 28 Nov 2016 16:54:18 +0100 Subject: [PATCH 022/214] show displayName in toolbar --- .../res/layout/custom_toolbar.xml | 38 ++++++++++++++ .../res/layout/fragment_container.xml | 38 +------------- .../res/layout/activity_tracking.xml | 50 ++++--------------- .../app/ui/activities/BuoyActivity.java | 2 +- .../app/ui/activities/RegattaActivity.java | 2 +- .../app/ui/activities/TrackingActivity.java | 2 +- 6 files changed, 53 insertions(+), 79 deletions(-) create mode 100644 mobile/com.sap.sailing.android.shared/res/layout/custom_toolbar.xml diff --git a/mobile/com.sap.sailing.android.shared/res/layout/custom_toolbar.xml b/mobile/com.sap.sailing.android.shared/res/layout/custom_toolbar.xml new file mode 100644 index 00000000000..970ce4bcc96 --- /dev/null +++ b/mobile/com.sap.sailing.android.shared/res/layout/custom_toolbar.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/mobile/com.sap.sailing.android.shared/res/layout/fragment_container.xml b/mobile/com.sap.sailing.android.shared/res/layout/fragment_container.xml index ff877f51324..a8440701dd2 100644 --- a/mobile/com.sap.sailing.android.shared/res/layout/fragment_container.xml +++ b/mobile/com.sap.sailing.android.shared/res/layout/fragment_container.xml @@ -3,43 +3,9 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - - - - - - - + layout="@layout/custom_toolbar" /> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/fiori_main_background"> - - - - - - - - - + layout="@layout/custom_toolbar" /> + android:background="@color/separator_color" /> + android:padding="0dp" /> + android:layout_weight="1" />