Merge branch 'master' into bug5627

This commit is contained in:
Axel Uhl
2022-12-30 15:47:34 +01:00
193 changed files with 1140 additions and 1283 deletions
-1
View File
@@ -14,7 +14,6 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.6.4' classpath 'com.android.tools.build:gradle:3.6.4'
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.3"
classpath "org.ajoberstar:grgit:2.3.0" classpath "org.ajoberstar:grgit:2.3.0"
} }
} }
+1 -1
View File
@@ -9,7 +9,7 @@ GWT_ROOT="${GWT}/trunk"
cd "${GWT}" cd "${GWT}"
echo "GWT directory: ${GWT}" echo "GWT directory: ${GWT}"
# Use the following two lines for the new gwt-2.10-api-checker stuff # Use the following two lines for the new gwt-2.10-api-checker stuff
git clone https://github.com/axeluhl/gwt.git -b issue-7987-compatibility trunk git clone https://github.com/axeluhl/gwt.git -b issue-7987-compatibility-with-issue-9584 trunk
git clone https://github.com/Vertispan/tools.git -b gwt-2.10-api-checker git clone https://github.com/Vertispan/tools.git -b gwt-2.10-api-checker
# Or alternatively: # Or alternatively:
#git clone https://github.com/axeluhl/gwt.git -b issue-7987-compatibility trunk #git clone https://github.com/axeluhl/gwt.git -b issue-7987-compatibility trunk
@@ -9,7 +9,7 @@ Fragment-Host: com.sap.sailing.datamining
Import-Package: junit.framework;version="4.8.2", Import-Package: junit.framework;version="4.8.2",
org.junit;version="4.8.2", org.junit;version="4.8.2",
org.junit.runner;version="4.8.2" org.junit.runner;version="4.8.2"
Require-Bundle: org.mockito.mockito-core;bundle-version="1.9.5", Require-Bundle: org.mockito.mockito-core;bundle-version="4.8.1",
org.hamcrest;bundle-version="2.2.0", org.hamcrest;bundle-version="2.2.0",
com.sap.sse.common, com.sap.sse.common,
org.objenesis;bundle-version="2.1.0" org.objenesis;bundle-version="2.1.0"
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.bravoadapter.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@@ -22,12 +23,12 @@ import com.sap.sse.common.impl.DegreeBearingImpl;
public class BravoGPSFixImporter implements GPSFixImporter { public class BravoGPSFixImporter implements GPSFixImporter {
@Override @Override
public boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, final String filename) public boolean importFixes(InputStream inputStream, Charset charset, Callback callback, boolean inferSpeedAndBearing, final String filename)
throws FormatNotSupportedException, IOException { throws FormatNotSupportedException, IOException {
final AtomicBoolean importedFixes = new AtomicBoolean(false); final AtomicBoolean importedFixes = new AtomicBoolean(false);
TrackFileImportDeviceIdentifier device = new TrackFileImportDeviceIdentifierImpl(filename, getType() + "@" + new Date()); TrackFileImportDeviceIdentifier device = new TrackFileImportDeviceIdentifierImpl(filename, getType() + "@" + new Date());
new BravoExtendedDataImporterImpl().importFixes(inputStream, new BravoExtendedDataImporterImpl().importFixes(inputStream,
(Iterable<DoubleVectorFix> fixes, TrackFileImportDeviceIdentifier deviceIdentifier)->{ charset, (Iterable<DoubleVectorFix> fixes, TrackFileImportDeviceIdentifier deviceIdentifier)->{
for (final DoubleVectorFix fix : fixes) { for (final DoubleVectorFix fix : fixes) {
GPSFixMoving gpsFix = new GPSFixMovingImpl( GPSFixMoving gpsFix = new GPSFixMovingImpl(
new DegreePosition(FunnyDegreeConverter.funnyLatLng(fix.get(BravoExtendedSensorDataMetadata.LAT.getColumnIndex())), new DegreePosition(FunnyDegreeConverter.funnyLatLng(fix.get(BravoExtendedSensorDataMetadata.LAT.getColumnIndex())),
@@ -39,7 +39,9 @@ public interface ScoreCorrectionProvider extends Named {
RegattaScoreCorrections getScoreCorrections(String eventName, String boatClassName, TimePoint timePoint) throws Exception; RegattaScoreCorrections getScoreCorrections(String eventName, String boatClassName, TimePoint timePoint) throws Exception;
/** /**
* Produces a single {@link RegattaScoreCorrections} object from a single {@link InputStream}. * Produces a single {@link RegattaScoreCorrections} object from a single {@link InputStream}. The implementing
* subclass defines the character set encoding used to read characters from the stream if the stream is not
* interpreted as a binary source anyway.
*/ */
RegattaScoreCorrections getScoreCorrections(InputStream inputStream) throws Exception; RegattaScoreCorrections getScoreCorrections(InputStream inputStream) throws Exception;
} }
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.deckmanadapter.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
@@ -19,8 +20,8 @@ import com.sap.sailing.domain.trackimport.GPSFixImporter;
public class DeckmanGPSFixImporter implements GPSFixImporter { public class DeckmanGPSFixImporter implements GPSFixImporter {
@Override @Override
public boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, public boolean importFixes(InputStream inputStream, Charset charset, Callback callback,
String sourceName) boolean inferSpeedAndBearing, String sourceName)
throws FormatNotSupportedException, IOException { throws FormatNotSupportedException, IOException {
DeckmanAdapter deckmanAdapter = DeckmanAdapterFactoryImpl.INSTANCE.createDeckmanAdapter(); DeckmanAdapter deckmanAdapter = DeckmanAdapterFactoryImpl.INSTANCE.createDeckmanAdapter();
TrackFileImportDeviceIdentifier device = new TrackFileImportDeviceIdentifierImpl(sourceName, getType() + "@" + new Date()); TrackFileImportDeviceIdentifier device = new TrackFileImportDeviceIdentifierImpl(sourceName, getType() + "@" + new Date());
@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@@ -29,16 +30,16 @@ public class ExpeditionGPSFixImporter implements GPSFixImporter {
private static final String SOG_COLUMN_HEADING = "sog"; private static final String SOG_COLUMN_HEADING = "sog";
@Override @Override
public boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, public boolean importFixes(InputStream inputStream, Charset charset, Callback callback,
final String sourceName) boolean inferSpeedAndBearing, final String sourceName)
throws FormatNotSupportedException, IOException { throws FormatNotSupportedException, IOException {
TrackFileImportDeviceIdentifier device = new TrackFileImportDeviceIdentifierImpl(sourceName, getType() + "@" + new Date()); TrackFileImportDeviceIdentifier device = new TrackFileImportDeviceIdentifierImpl(sourceName, getType() + "@" + new Date());
final AtomicBoolean importedFixes = new AtomicBoolean(false); final AtomicBoolean importedFixes = new AtomicBoolean(false);
CompressedStreamsUtil.handlePotentiallyCompressedFiles(sourceName, inputStream, CompressedStreamsUtil.handlePotentiallyCompressedFiles(sourceName, inputStream,
new ExpeditionImportFileHandler() { charset, new ExpeditionImportFileHandler() {
@Override @Override
protected void handleExpeditionFile(String fileName, InputStream stream) throws IOException { protected void handleExpeditionFile(String fileName, InputStream stream, Charset charset) throws IOException {
final BufferedReader br = new BufferedReader(new InputStreamReader(stream)); final BufferedReader br = new BufferedReader(new InputStreamReader(stream, charset));
final String headerLine = br.readLine(); final String headerLine = br.readLine();
final Map<String, Integer> columnDefinitions = ExpeditionExtendedDataImporterImpl final Map<String, Integer> columnDefinitions = ExpeditionExtendedDataImporterImpl
.parseHeader(headerLine); .parseHeader(headerLine);
@@ -22,13 +22,15 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.sap.sse.util.HttpUrlConnectionHelper;
public class ConnectivityUtils { public class ConnectivityUtils {
public static JSONObject getJsonFromResponse(HttpResponse response) throws IllegalStateException, IOException, ParseException { public static JSONObject getJsonFromResponse(HttpResponse response) throws IllegalStateException, IOException, ParseException {
JSONParser jsonParser = new JSONParser(); JSONParser jsonParser = new JSONParser();
final Header contentEncoding = response.getEntity().getContentEncoding(); final Header contentEncoding = response.getEntity().getContentEncoding();
final Reader reader; final Reader reader;
if (contentEncoding == null) { if (contentEncoding == null) {
reader = new InputStreamReader(response.getEntity().getContent()); reader = new InputStreamReader(response.getEntity().getContent(), HttpUrlConnectionHelper.getCharsetFromHttpEntity(response.getEntity(), "UTF-8"));
} else { } else {
reader = new InputStreamReader(response.getEntity().getContent(), contentEncoding.getValue()); reader = new InputStreamReader(response.getEntity().getContent(), contentEncoding.getValue());
} }
@@ -40,7 +42,8 @@ public class ConnectivityUtils {
public static String getContent(HttpResponse response) throws IOException { public static String getContent(HttpResponse response) throws IOException {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
String line; String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(),
HttpUrlConnectionHelper.getCharsetFromHttpEntity(response.getEntity(), "UTF-8")));
while ((line=reader.readLine()) != null) { while ((line=reader.readLine()) != null) {
result.append(line); result.append(line);
result.append('\n'); result.append('\n');
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.oceanraceadapter.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -44,8 +45,8 @@ public class OceanRaceGPSFixImporter implements GPSFixImporter {
private final Map<Pair<String, String>, TrackFileImportDeviceIdentifier> deviceIdentifiersBySerialAndSourceName = new HashMap<>(); private final Map<Pair<String, String>, TrackFileImportDeviceIdentifier> deviceIdentifiersBySerialAndSourceName = new HashMap<>();
@Override @Override
public boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, public boolean importFixes(InputStream inputStream, Charset charset, Callback callback,
String sourceName) throws FormatNotSupportedException, IOException, ParseException { boolean inferSpeedAndBearing, String sourceName) throws FormatNotSupportedException, IOException, ParseException {
final JSONParser jsonParser = new JSONParser(); final JSONParser jsonParser = new JSONParser();
final JSONArray boatsArray = (JSONArray) jsonParser.parse(new InputStreamReader(inputStream)); final JSONArray boatsArray = (JSONArray) jsonParser.parse(new InputStreamReader(inputStream));
for (final Object objectForBoat : boatsArray) { for (final Object objectForBoat : boatsArray) {
@@ -21,5 +21,7 @@ Import-Package: com.sap.sailing.domain.abstractlog.regatta.events,
com.sap.sailing.server.impl, com.sap.sailing.server.impl,
com.sap.sailing.server.util, com.sap.sailing.server.util,
com.sap.sse.concurrent, com.sap.sse.concurrent,
javax.servlet.http;version="3.1.0" javax.servlet.http;version="3.1.0",
org.apache.http;version="4.4.9",
org.apache.http.entity;version="4.4.9"
Automatic-Module-Name: com.sap.sailing.domain.racelogtrackingadapter.test Automatic-Module-Name: com.sap.sailing.domain.racelogtrackingadapter.test
@@ -7,10 +7,13 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset;
import org.json.simple.JSONValue; import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import com.sap.sse.util.HttpUrlConnectionHelper;
public abstract class AbstractJsonOverHttpTest { public abstract class AbstractJsonOverHttpTest {
protected static final String URL_BASE = "127.0.0.1"; protected static final String URL_BASE = "127.0.0.1";
protected static final int PORT = 8888; protected static final int PORT = 8888;
@@ -52,8 +55,8 @@ public abstract class AbstractJsonOverHttpTest {
if (is == null) { if (is == null) {
return ""; return "";
} }
final Charset cs = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
BufferedReader rd = new BufferedReader(new InputStreamReader(is)); BufferedReader rd = new BufferedReader(new InputStreamReader(is, cs));
String line; String line;
StringBuffer response = new StringBuffer(); StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) { while ((line = rd.readLine()) != null) {
@@ -29,25 +29,25 @@ public class LogEventComparator implements Comparator<Timed>, Serializable {
if (o1 instanceof AbstractLogEvent && o2 instanceof AbstractLogEvent) { if (o1 instanceof AbstractLogEvent && o2 instanceof AbstractLogEvent) {
return compareEvents((AbstractLogEvent<?>) o1, (AbstractLogEvent<?>) o2); return compareEvents((AbstractLogEvent<?>) o1, (AbstractLogEvent<?>) o2);
} }
// fallback to timed comparison // fallback to timed comparison
return timedComparator.compare(o1, o2); return timedComparator.compare(o1, o2);
} }
protected int compareEvents(AbstractLogEvent<?> e1, AbstractLogEvent<?> e2) { protected int compareEvents(AbstractLogEvent<?> e1, AbstractLogEvent<?> e2) {
//compare author priorities // compare author priorities
int result = e1.getAuthor().compareTo(e2.getAuthor()); int result = e1.getAuthor().compareTo(e2.getAuthor());
if (result != 0) return result; if (result == 0) {
// compare created at timepoints
//compare created at timepoints result = e1.getCreatedAt().compareTo(e2.getCreatedAt());
result = e1.getCreatedAt().compareTo(e2.getCreatedAt()); if (result == 0) {
if (result != 0) return result; // compare logical timepoints
result = Util.compareToWithNull(e1.getLogicalTimePoint(), e2.getLogicalTimePoint(), /* nullIsLess */ false);
//compare logical timepoints if (result == 0) {
result = Util.compareToWithNull(e1.getLogicalTimePoint(), e2.getLogicalTimePoint(), /* nullIsLess */ false); // compare ids
if (result != 0) return result; result = e1.getId().toString().compareTo(e2.getId().toString());
}
//compare ids }
return e1.getId().toString().compareTo(e2.getId().toString()); }
return result;
} }
} }
@@ -9,6 +9,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.charset.Charset;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.text.ParseException; import java.text.ParseException;
import java.util.List; import java.util.List;
@@ -39,7 +40,8 @@ public class SwissTimingRaceConfigurationTest {
URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "446483")); URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "446483"));
URLConnection connection = configFileURL.openConnection(); URLConnection connection = configFileURL.openConnection();
InputStream configDataStream = connection.getInputStream(); InputStream configDataStream = connection.getInputStream();
SwissTimingRaceConfig config_446483 = new SwissTimingReplayServiceImpl(DomainFactory.INSTANCE).loadRaceConfig(configDataStream); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
SwissTimingRaceConfig config_446483 = new SwissTimingReplayServiceImpl(DomainFactory.INSTANCE).loadRaceConfig(configDataStream, charset);
assertNotNull(config_446483); assertNotNull(config_446483);
assertEquals("GB", config_446483.country_code); assertEquals("GB", config_446483.country_code);
assertNull(config_446483.event_name); assertNull(config_446483.event_name);
@@ -57,7 +59,8 @@ public class SwissTimingRaceConfigurationTest {
URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "6260")); URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "6260"));
URLConnection connection = configFileURL.openConnection(); URLConnection connection = configFileURL.openConnection();
InputStream configDataStream = connection.getInputStream(); InputStream configDataStream = connection.getInputStream();
SwissTimingRaceConfig config_446483 = new SwissTimingReplayServiceImpl(DomainFactory.INSTANCE).loadRaceConfig(configDataStream); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
SwissTimingRaceConfig config_446483 = new SwissTimingReplayServiceImpl(DomainFactory.INSTANCE).loadRaceConfig(configDataStream, charset);
assertNotNull(config_446483); assertNotNull(config_446483);
assertEquals("GB", config_446483.country_code); assertEquals("GB", config_446483.country_code);
// TODO There used to be an attribute event_name in the "config" sub-element; around 2017-07-25 these things seem to have vanished; // TODO There used to be an attribute event_name in the "config" sub-element; around 2017-07-25 these things seem to have vanished;
@@ -5,6 +5,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.util.List; import java.util.List;
@@ -23,7 +24,7 @@ public interface SwissTimingReplayService {
List<SwissTimingReplayRace> listReplayRaces(String swissTimingUrlText); List<SwissTimingReplayRace> listReplayRaces(String swissTimingUrlText);
SwissTimingRaceConfig loadRaceConfig(InputStream configDataStream) throws IOException, SwissTimingRaceConfig loadRaceConfig(InputStream configDataStream, Charset charset) throws IOException,
org.json.simple.parser.ParseException; org.json.simple.parser.ParseException;
DateFormat getStartTimeFormat(); DateFormat getStartTimeFormat();
@@ -8,6 +8,8 @@ import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.text.ParseException; import java.text.ParseException;
@@ -64,15 +66,17 @@ public class SwissTimingReplayServiceImpl implements SwissTimingReplayService {
public SwissTimingRaceConfig loadRaceConfig(String raceId) { public SwissTimingRaceConfig loadRaceConfig(String raceId) {
try { try {
URL configUrl = new URL(MessageFormat.format(RACE_CONFIG_URL_TEMPLATE, raceId)); URL configUrl = new URL(MessageFormat.format(RACE_CONFIG_URL_TEMPLATE, raceId));
InputStream configDataStream = configUrl.openStream(); final URLConnection connection = configUrl.openConnection();
return loadRaceConfig(configDataStream); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
InputStream configDataStream = connection.getInputStream();
return loadRaceConfig(configDataStream, charset);
} catch (Exception e) { // MalformedURLException | ParseException | org.json.simple.parser.ParseException) } catch (Exception e) { // MalformedURLException | ParseException | org.json.simple.parser.ParseException)
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@Override @Override
public SwissTimingRaceConfig loadRaceConfig(InputStream configDataStream) throws IOException, public SwissTimingRaceConfig loadRaceConfig(InputStream configDataStream, Charset charset) throws IOException,
org.json.simple.parser.ParseException { org.json.simple.parser.ParseException {
JSONObject jsonRaceConfig = (JSONObject) new JSONParser().parse(new InputStreamReader(configDataStream)); JSONObject jsonRaceConfig = (JSONObject) new JSONParser().parse(new InputStreamReader(configDataStream));
JSONObject jsonConfigEntry = (JSONObject) jsonRaceConfig.get("config"); JSONObject jsonConfigEntry = (JSONObject) jsonRaceConfig.get("config");
@@ -1,20 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> <launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test"/> <listEntry value="/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=com.sap.sailing.domain.test/src&lt;com.sap.sailing.domain.test"/> <stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=com.sap.sailing.domain.test/src=/test=/true=/&lt;com.sap.sailing.domain.test"/>
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> <booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> <stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.domain.test"/> <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dtractrac.tunnel=true"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.domain.test"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dtractrac.tunnel=true"/>
</launchConfiguration> </launchConfiguration>
@@ -89,7 +89,7 @@ public class TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog {
} }
@Test @Test
public void testCertificateAssignments() { public void testCertificateAssignments() throws InterruptedException {
// no logs attached; therefore no certs // no logs attached; therefore no certs
assertNoCertificate(boat1); assertNoCertificate(boat1);
assertNoCertificate(boat2); assertNoCertificate(boat2);
@@ -101,16 +101,20 @@ public class TestORCRankingMetricCollaborationWithRaceLogAndRegattaLog {
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert1, boat1, authorP1)); regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert1, boat1, authorP1));
assertCertificate(boat1, boat1RegattaCert1); assertCertificate(boat1, boat1RegattaCert1);
ORCCertificate boat1RegattaCert2 = mock(ORCCertificate.class); ORCCertificate boat1RegattaCert2 = mock(ORCCertificate.class);
Thread.sleep(10); // ensure we get a new timestamp
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert2, boat1, authorP2)); regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert2, boat1, authorP2));
// the priority for Cert2 was 2 and therefore the P1 assignment still takes precedence // the priority for Cert2 was 2 and therefore the P1 assignment still takes precedence
assertCertificate(boat1, boat1RegattaCert1); assertCertificate(boat1, boat1RegattaCert1);
Thread.sleep(10); // ensure we get a new timestamp
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert2, boat1, authorP1)); regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat1RegattaCert2, boat1, authorP1));
assertCertificate(boat1, boat1RegattaCert2); assertCertificate(boat1, boat1RegattaCert2);
ORCCertificate boat2RegattaCert1 = mock(ORCCertificate.class); ORCCertificate boat2RegattaCert1 = mock(ORCCertificate.class);
Thread.sleep(10); // ensure we get a new timestamp
regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat2RegattaCert1, boat2, authorP2)); regattaLog.add(createRegattaLogCertificateAssignmentEvent(boat2RegattaCert1, boat2, authorP2));
assertCertificate(boat2, boat2RegattaCert1); assertCertificate(boat2, boat2RegattaCert1);
// now override on race log level: // now override on race log level:
ORCCertificate boat1RaceCert1 = mock(ORCCertificate.class); ORCCertificate boat1RaceCert1 = mock(ORCCertificate.class);
Thread.sleep(10); // ensure we get a new timestamp
raceLog.add(createRaceLogCertificateAssignmentEvent(boat1RaceCert1, boat1, authorP2)); raceLog.add(createRaceLogCertificateAssignmentEvent(boat1RaceCert1, boat1, authorP2));
assertCertificate(boat1, boat1RaceCert1); assertCertificate(boat1, boat1RaceCert1);
trackedRace.detachRaceLog(raceLog.getId()); trackedRace.detachRaceLog(raceLog.getId());
@@ -6,6 +6,8 @@ import java.io.InputStreamReader;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -142,8 +144,9 @@ public class RaceRecord {
private Map<String, String> parseParams(URL paramURL) throws IOException { private Map<String, String> parseParams(URL paramURL) throws IOException {
Map<String, String> result = new HashMap<String, String>(); Map<String, String> result = new HashMap<String, String>();
Pattern pattern = Pattern.compile("^([^:]*):(.*)$"); Pattern pattern = Pattern.compile("^([^:]*):(.*)$");
BufferedReader r = new BufferedReader(new InputStreamReader( final URLConnection connection = HttpUrlConnectionHelper.redirectConnection(paramURL);
HttpUrlConnectionHelper.redirectConnection(paramURL).getInputStream())); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
BufferedReader r = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset));
String line; String line;
while ((line = r.readLine()) != null) { while ((line = r.readLine()) != null) {
Matcher matcher = pattern.matcher(line); Matcher matcher = pattern.matcher(line);
@@ -5,6 +5,8 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -16,13 +18,16 @@ import org.json.simple.parser.JSONParser;
import com.sap.sailing.domain.tractracadapter.JSONService; import com.sap.sailing.domain.tractracadapter.JSONService;
import com.sap.sailing.domain.tractracadapter.RaceRecord; import com.sap.sailing.domain.tractracadapter.RaceRecord;
import com.sap.sse.util.HttpUrlConnectionHelper;
public class JSONServiceImpl implements JSONService { public class JSONServiceImpl implements JSONService {
private final String regattaName; private final String regattaName;
private final List<RaceRecord> raceRecords; private final List<RaceRecord> raceRecords;
public JSONServiceImpl(URL jsonURL, boolean loadLiveAndStoredURI) throws IOException, ParseException, org.json.simple.parser.ParseException, URISyntaxException { public JSONServiceImpl(URL jsonURL, boolean loadLiveAndStoredURI) throws IOException, ParseException, org.json.simple.parser.ParseException, URISyntaxException {
JSONObject jsonObject = parseJSONObject(jsonURL.openStream()); final URLConnection connection = jsonURL.openConnection();
final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
JSONObject jsonObject = parseJSONObject(connection.getInputStream(), charset);
raceRecords = new ArrayList<RaceRecord>(); raceRecords = new ArrayList<RaceRecord>();
regattaName = (String) ((JSONObject) jsonObject.get("event")).get("name"); regattaName = (String) ((JSONObject) jsonObject.get("event")).get("name");
for (Object raceEntry : (JSONArray) jsonObject.get("races")) { for (Object raceEntry : (JSONArray) jsonObject.get("races")) {
@@ -50,7 +55,9 @@ public class JSONServiceImpl implements JSONService {
} }
public JSONServiceImpl(URL jsonURL, String raceEntryId, boolean loadLiveAndStoredURI) throws IOException, ParseException, org.json.simple.parser.ParseException, URISyntaxException { public JSONServiceImpl(URL jsonURL, String raceEntryId, boolean loadLiveAndStoredURI) throws IOException, ParseException, org.json.simple.parser.ParseException, URISyntaxException {
JSONObject jsonObject = parseJSONObject(jsonURL.openStream()); final URLConnection connection = jsonURL.openConnection();
final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
JSONObject jsonObject = parseJSONObject(connection.getInputStream(), charset);
raceRecords = new ArrayList<RaceRecord>(); raceRecords = new ArrayList<RaceRecord>();
regattaName = (String) ((JSONObject) jsonObject.get("event")).get("name"); regattaName = (String) ((JSONObject) jsonObject.get("event")).get("name");
for (Object raceEntry : (JSONArray) jsonObject.get("races")) { for (Object raceEntry : (JSONArray) jsonObject.get("races")) {
@@ -72,7 +79,7 @@ public class JSONServiceImpl implements JSONService {
return Collections.unmodifiableList(raceRecords); return Collections.unmodifiableList(raceRecords);
} }
private JSONObject parseJSONObject(InputStream is) throws IOException, ParseException, org.json.simple.parser.ParseException { private JSONObject parseJSONObject(InputStream is, Charset charset) throws IOException, ParseException, org.json.simple.parser.ParseException {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
Object result = parser.parse(new InputStreamReader(is)); Object result = parser.parse(new InputStreamReader(is));
return (JSONObject) result; return (JSONObject) result;
@@ -5,6 +5,8 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -108,15 +110,21 @@ public class ReviewedSpotsCollectionImpl implements ReviewedSpotsCollection {
private Iterable<Spot> loadSpots() { private Iterable<Spot> loadSpots() {
Iterable<Spot> result = Collections.emptySet(); Iterable<Spot> result = Collections.emptySet();
if (!backoffTracker.backOff()) { if (!backoffTracker.backOff()) {
try (InputStreamReader in = new InputStreamReader((InputStream) HttpUrlConnectionHelper try {
.redirectConnection( final URLConnection connection = HttpUrlConnectionHelper
new URL(Activator.BASE_URL_FOR_JSON_DOCUMENTS + "/" + getId() + SPOT_LIST_DOCUMENT_SUFFIX), .redirectConnection(
/* timeout */ Duration.ONE_SECOND.times(10), /* preConnectionModifier */ null) new URL(Activator.BASE_URL_FOR_JSON_DOCUMENTS + "/" + getId() + SPOT_LIST_DOCUMENT_SUFFIX),
.getContent())) { /* timeout */ Duration.ONE_SECOND.times(10), /* preConnectionModifier */ null);
JSONArray spotsAsJson = (JSONArray) new JSONParser().parse(in); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
result = parser.parseSpots(spotsAsJson, this); try (InputStreamReader in = new InputStreamReader((InputStream) connection.getContent(), charset)) {
backoffTracker.clear(); JSONArray spotsAsJson = (JSONArray) new JSONParser().parse(in);
} catch (Exception e) { result = parser.parseSpots(spotsAsJson, this);
backoffTracker.clear();
} catch (IOException | ParseException e) {
logger.log(Level.SEVERE, "Problem loading spots for spot collection " + id, e);
backoffTracker.logFailure();
}
} catch (IOException e) {
logger.log(Level.SEVERE, "Problem loading spots for spot collection " + id, e); logger.log(Level.SEVERE, "Problem loading spots for spot collection " + id, e);
backoffTracker.logFailure(); backoffTracker.logFailure();
} }
@@ -5,6 +5,8 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -117,9 +119,10 @@ public class SpotImpl extends SpotDTO implements Spot {
@Override @Override
public Iterable<Wind> getAllMeasurements() public Iterable<Wind> getAllMeasurements()
throws IOException, MalformedURLException, ParseException, org.json.simple.parser.ParseException { throws IOException, MalformedURLException, ParseException, org.json.simple.parser.ParseException {
final InputStream response = (InputStream) HttpUrlConnectionHelper.redirectConnection( final URLConnection connection = HttpUrlConnectionHelper.redirectConnection(getMeasurementsUrl());
getMeasurementsUrl()).getContent(); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
final Iterable<Wind> measurements = parser.parse(getPosition(), (JSONArray) new JSONParser().parse(new InputStreamReader(response))); final InputStream response = (InputStream) connection.getContent();
final Iterable<Wind> measurements = parser.parse(getPosition(), (JSONArray) new JSONParser().parse(new InputStreamReader(response, charset)));
return measurements; return measurements;
} }
@@ -5,6 +5,8 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -76,9 +78,11 @@ public class YellowBrickCompetitorProvider extends AbstractResultUrlProvider imp
throws JAXBException, IOException { throws JAXBException, IOException {
// assumes that the eventName is the URL // assumes that the eventName is the URL
final Set<CompetitorDescriptor> result = new HashSet<>(); final Set<CompetitorDescriptor> result = new HashSet<>();
final InputStream inputStream = (InputStream) HttpUrlConnectionHelper.redirectConnection(new URL(eventNameWhichIsTheURL)).getContent(); final URLConnection connection = HttpUrlConnectionHelper.redirectConnection(new URL(eventNameWhichIsTheURL));
final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
final InputStream inputStream = (InputStream) connection.getContent();
final CSVParser csvParser = new CSVParser(); final CSVParser csvParser = new CSVParser();
final Pair<List<String>, Iterable<List<String>>> content = csvParser.parseWithHeader(new InputStreamReader(inputStream)); final Pair<List<String>, Iterable<List<String>>> content = csvParser.parseWithHeader(new InputStreamReader(inputStream, charset));
for (final List<String> competitorLine : content.getB()) { for (final List<String> competitorLine : content.getB()) {
result.add(parseIntoCompetitorDescriptor(/* header */ content.getA(), competitorLine)); result.add(parseIntoCompetitorDescriptor(/* header */ content.getA(), competitorLine));
} }
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.yellowbrickadapter.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -22,8 +23,8 @@ public class YellowBrickGPSFixImporter implements GPSFixImporter {
private final ConcurrentMap<Pair<Number, String>, TrackFileImportDeviceIdentifier> deviceIdentifiersBySerialAndSourceName = new ConcurrentHashMap<>(); private final ConcurrentMap<Pair<Number, String>, TrackFileImportDeviceIdentifier> deviceIdentifiersBySerialAndSourceName = new ConcurrentHashMap<>();
@Override @Override
public boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, public boolean importFixes(InputStream inputStream, Charset charset, Callback callback,
String sourceName) throws FormatNotSupportedException, IOException, ParseException { boolean inferSpeedAndBearing, String sourceName) throws FormatNotSupportedException, IOException, ParseException {
final GetPositionsParser parser = new GetPositionsParser(); final GetPositionsParser parser = new GetPositionsParser();
final PositionsDocument positionsDocument = parser.parse(new InputStreamReader(inputStream, "UTF-8"), inferSpeedAndBearing); final PositionsDocument positionsDocument = parser.parse(new InputStreamReader(inputStream, "UTF-8"), inferSpeedAndBearing);
final String raceName = positionsDocument.getRaceUrl(); final String raceName = positionsDocument.getRaceUrl();
@@ -8,6 +8,7 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
@@ -127,8 +128,9 @@ public class YellowBrickTrackingAdapterImpl implements YellowBrickTrackingAdapte
private PositionsDocument getPositionsDocumentForUrl(final String url) private PositionsDocument getPositionsDocumentForUrl(final String url)
throws MalformedURLException, IOException, ParseException { throws MalformedURLException, IOException, ParseException {
final URLConnection result = HttpUrlConnectionHelper.redirectConnectionWithBearerToken(new URL(url), TIMEOUT_FOR_RACE_LOADING, /* bearer token */ null); final URLConnection result = HttpUrlConnectionHelper.redirectConnectionWithBearerToken(new URL(url), TIMEOUT_FOR_RACE_LOADING, /* bearer token */ null);
final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(result, "UTF-8");
final InputStream inputStream = (InputStream) result.getContent(); final InputStream inputStream = (InputStream) result.getContent();
final PositionsDocument doc = new GetPositionsParser().parse(new InputStreamReader(inputStream), /* inferSpeedAndBearing */ true); final PositionsDocument doc = new GetPositionsParser().parse(new InputStreamReader(inputStream, charset), /* inferSpeedAndBearing */ true);
return doc; return doc;
} }
@@ -60,6 +60,7 @@ Import-Package: com.sap.sse.security,
com.sap.sse.security.shared, com.sap.sse.security.shared,
com.sap.sse.security.shared.dto, com.sap.sse.security.shared.dto,
com.sap.sse.security.shared.impl, com.sap.sse.security.shared.impl,
javax.xml.bind,
org.apache.commons.io;version="2.2.0", org.apache.commons.io;version="2.2.0",
org.apache.commons.io.input;version="2.2.0", org.apache.commons.io.input;version="2.2.0",
org.apache.commons.lang;version="2.6.0", org.apache.commons.lang;version="2.6.0",
@@ -67,7 +68,7 @@ Import-Package: com.sap.sse.security,
org.apache.http.client;version="4.5.5", org.apache.http.client;version="4.5.5",
org.apache.http.client.entity;version="4.5.5", org.apache.http.client.entity;version="4.5.5",
org.apache.http.client.methods;version="4.5.5", org.apache.http.client.methods;version="4.5.5",
org.apache.http.entity;version="4.4.9",
org.apache.http.impl.client;version="4.5.5", org.apache.http.impl.client;version="4.5.5",
org.apache.http.message;version="4.4.9", org.apache.http.message;version="4.4.9"
javax.xml.bind
Automatic-Module-Name: com.sap.sailing.domain Automatic-Module-Name: com.sap.sailing.domain
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.trackimport;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import com.sap.sailing.domain.common.tracking.DoubleVectorFix; import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier; import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier;
@@ -19,6 +20,7 @@ public interface BaseDoubleVectorFixImporter {
* *
* @param inputStream * @param inputStream
* the uploaded file as {@link InputStream} * the uploaded file as {@link InputStream}
* @param charset the character set to use to decode the {@code inputStream}
* @param callback * @param callback
* the callback to call for every new fix * the callback to call for every new fix
* @param sourceName * @param sourceName
@@ -33,8 +35,8 @@ public interface BaseDoubleVectorFixImporter {
* @throws IOException * @throws IOException
* if there is a problem while reading the file * if there is a problem while reading the file
*/ */
boolean importFixes(InputStream inputStream, Callback callback, String filename, String sourceName, boolean importFixes(InputStream inputStream, Charset charset, Callback callback, String filename,
boolean downsample) String sourceName, boolean downsample)
throws FormatNotSupportedException, IOException; throws FormatNotSupportedException, IOException;
/** /**
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.trackimport; package com.sap.sailing.domain.trackimport;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Map; import java.util.Map;
import com.sap.sailing.domain.common.DeviceIdentifier; import com.sap.sailing.domain.common.DeviceIdentifier;
@@ -45,19 +46,20 @@ public interface GPSFixImporter {
/** /**
* Retrieves the fixes from the {@code inputStream}, and calls the {@code callback} with every new fix. * Retrieves the fixes from the {@code inputStream}, and calls the {@code callback} with every new fix.
* * @param charset TODO
* @param inferSpeedAndBearing * @param inferSpeedAndBearing
* Should speed and bearing be inferred by looking at the previous fix, if that data is not directly * Should speed and bearing be inferred by looking at the previous fix, if that data is not directly
* present within the file? * present within the file?
* @param sourceName
* some name that identifies the source, e.g. the file name if a file
*
* @throws FormatNotSupportedException * @throws FormatNotSupportedException
* If the input format cannot be read. The import process might then decide to try attempt importing * If the input format cannot be read. The import process might then decide to try attempt importing
* fixes using the next suitable importer. * fixes using the next suitable importer.
* *
* @param sourceName
* some name that identifies the source, e.g. the file name if a file
* @return returns if import was succesful or not * @return returns if import was succesful or not
*/ */
boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, String sourceName) throws Exception; boolean importFixes(InputStream inputStream, Charset charset, Callback callback, boolean inferSpeedAndBearing, String sourceName) throws Exception;
/** /**
* Return the file extensions supported by this importer. If the importer is not intended * Return the file extensions supported by this importer. If the importer is not intended
@@ -21,6 +21,7 @@ import org.json.simple.parser.ParseException;
import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.util.HttpUrlConnectionHelper;
import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes; import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes;
public class FinishTimeUpdateHandler extends UpdateHandler { public class FinishTimeUpdateHandler extends UpdateHandler {
@@ -65,7 +66,8 @@ public class FinishTimeUpdateHandler extends UpdateHandler {
logger.info("Using " + stopTrackingURI.toString() + " to stop tracking"); logger.info("Using " + stopTrackingURI.toString() + " to stop tracking");
final HttpResponse response = client.execute(request); final HttpResponse response = client.execute(request);
try { try {
parseAndLogResponse(new BufferedReader(new InputStreamReader(response.getEntity().getContent()))); parseAndLogResponse(new BufferedReader(new InputStreamReader(response.getEntity().getContent(),
HttpUrlConnectionHelper.getCharsetFromHttpEntity(response.getEntity(), "UTF-8"))));
} catch (ParseException e) { } catch (ParseException e) {
logger.log(Level.INFO, "Error parsing TracTrac response for stop tracking", e); logger.log(Level.INFO, "Error parsing TracTrac response for stop tracking", e);
} }
@@ -27,6 +27,7 @@ import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.tracking.StartTimeChangedListener; import com.sap.sailing.domain.tracking.StartTimeChangedListener;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.util.HttpUrlConnectionHelper;
import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes; import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes;
public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeChangedListener { public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeChangedListener {
@@ -98,7 +99,8 @@ public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeCh
logger.info("Using " + startTrackingURI.toString() + " to start tracking"); logger.info("Using " + startTrackingURI.toString() + " to start tracking");
final HttpResponse response = client.execute(request); final HttpResponse response = client.execute(request);
try { try {
parseAndLogResponse(new BufferedReader(new InputStreamReader(response.getEntity().getContent()))); parseAndLogResponse(new BufferedReader(new InputStreamReader(response.getEntity().getContent(),
HttpUrlConnectionHelper.getCharsetFromHttpEntity(response.getEntity(), "UTF-8"))));
} catch (ParseException e) { } catch (ParseException e) {
logger.log(Level.INFO, "Error parsing TracTrac response for start tracking", e); logger.log(Level.INFO, "Error parsing TracTrac response for start tracking", e);
} }
@@ -13,6 +13,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -30,6 +31,7 @@ import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
import com.sap.sse.shared.json.JsonDeserializationException; import com.sap.sse.shared.json.JsonDeserializationException;
import com.sap.sse.shared.json.JsonDeserializer; import com.sap.sse.shared.json.JsonDeserializer;
import com.sap.sse.util.HttpUrlConnectionHelper;
/** /**
* An update handler can be registered as a listener on a {@link TrackedRace} and can then propagate information to * An update handler can be registered as a listener on a {@link TrackedRace} and can then propagate information to
@@ -148,7 +150,8 @@ public class UpdateHandler {
private BufferedReader getResponseOnUpdateFromProvider(HttpURLConnection connection) throws IOException { private BufferedReader getResponseOnUpdateFromProvider(HttpURLConnection connection) throws IOException {
InputStream inputStream = connection.getInputStream(); InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset));
return reader; return reader;
} }
@@ -6,7 +6,8 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.sap.sailing.ess40.resultimport.Activator Bundle-Activator: com.sap.sailing.ess40.resultimport.Activator
Bundle-Vendor: SAP Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0" Import-Package: com.sap.sse.util,
org.osgi.framework;version="1.3.0"
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Require-Bundle: com.sap.sailing.domain, Require-Bundle: com.sap.sailing.domain,
com.sap.sailing.domain.common, com.sap.sailing.domain.common,
@@ -7,6 +7,7 @@ import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -22,6 +23,7 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair; import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.util.HttpUrlConnectionHelper;
public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider { public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider {
private static final long serialVersionUID = -4870646572106575667L; private static final long serialVersionUID = -4870646572106575667L;
@@ -112,7 +114,8 @@ public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider {
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36");
conn.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); conn.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
conn.setRequestProperty("accept-language", "en-US,en;q=0.8,de;q=0.6,da;q=0.4"); conn.setRequestProperty("accept-language", "en-US,en;q=0.8,de;q=0.6,da;q=0.4");
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(conn, "UTF-8");
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
String readLine; String readLine;
while ((readLine = br.readLine()) != null) { while ((readLine = br.readLine()) != null) {
Matcher m = p.matcher(readLine); Matcher m = p.matcher(readLine);
@@ -5,11 +5,13 @@ import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset;
import java.util.logging.Logger; import java.util.logging.Logger;
import com.sap.sailing.domain.common.HttpMessageSenderServletConstants; import com.sap.sailing.domain.common.HttpMessageSenderServletConstants;
import com.sap.sailing.expeditionconnector.impl.HttpServletMessageReceiver.Receiver; import com.sap.sailing.expeditionconnector.impl.HttpServletMessageReceiver.Receiver;
import com.sap.sse.common.Base64Utils; import com.sap.sse.common.Base64Utils;
import com.sap.sse.util.HttpUrlConnectionHelper;
public class HttpServletMessageReceiverReader implements Runnable { public class HttpServletMessageReceiverReader implements Runnable {
private static final Logger logger = Logger.getLogger(HttpServletMessageReceiverReader.class.getName()); private static final Logger logger = Logger.getLogger(HttpServletMessageReceiverReader.class.getName());
@@ -105,6 +107,7 @@ public class HttpServletMessageReceiverReader implements Runnable {
*/ */
private void establishConnection() throws IOException { private void establishConnection() throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
reader = new InputStreamReader(connection.getInputStream()); final Charset charset = HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8");
reader = new InputStreamReader(connection.getInputStream(), charset);
} }
} }
@@ -156,13 +156,14 @@ public class GribWindFieldFactoryImpl implements GribWindFieldFactory {
} }
@Override @Override
public GribWindField createGribWindFieldFromStreams(Map<InputStream, String> streamsAndFilenames) throws IOException { public GribWindField createGribWindFieldFromStreams(
Map<InputStream, String> streamsAndFilenames) throws IOException {
return createGribWindFieldFromStreams(logger, DEFAULT_ERROR_LOG_LEVEL, streamsAndFilenames); return createGribWindFieldFromStreams(logger, DEFAULT_ERROR_LOG_LEVEL, streamsAndFilenames);
} }
@Override @Override
public GribWindField createGribWindFieldFromStreams(Logger logger, Level level, Map<InputStream, String> streamsAndFilenames) public GribWindField createGribWindFieldFromStreams(Logger logger, Level level,
throws IOException { Map<InputStream, String> streamsAndFilenames) throws IOException {
return createGribWindFieldFromStreams(createLogFormatter(logger, level), streamsAndFilenames); return createGribWindFieldFromStreams(createLogFormatter(logger, level), streamsAndFilenames);
} }
@@ -34,6 +34,8 @@
</listAttribute> </listAttribute>
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/> <booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/> <booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> <listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
@@ -119,6 +121,7 @@
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sailing.gwt.ui"/> <stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -style PRETTY -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html -startupUrl /gwt/AdminConsole.html -startupUrl /gwt/PairingList.html -startupUrl /gwt/LeaderboardEditing.html -startupUrl /gwt/Leaderboard.html -startupUrl /gwt/Spectator.html -startupUrl /gwt/EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html -startupUrl /gwt/RegattaOverview.html -startupUrl /gwt/DataMining.html -startupUrl /gwt/Simulator.html -startupUrl /gwt/VideoPopup.html -startupUrl /gwt/AutoPlay.html -startupUrl /gwt/YoutubePopup.html com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.PairingList com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.autoplay.AutoPlay"/> <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -style PRETTY -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html -startupUrl /gwt/AdminConsole.html -startupUrl /gwt/PairingList.html -startupUrl /gwt/LeaderboardEditing.html -startupUrl /gwt/Leaderboard.html -startupUrl /gwt/Spectator.html -startupUrl /gwt/EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html -startupUrl /gwt/RegattaOverview.html -startupUrl /gwt/DataMining.html -startupUrl /gwt/Simulator.html -startupUrl /gwt/VideoPopup.html -startupUrl /gwt/AutoPlay.html -startupUrl /gwt/YoutubePopup.html com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.PairingList com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.autoplay.AutoPlay"/>
@@ -543,7 +543,6 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel i
public void refreshTracTracConnectors() { public void refreshTracTracConnectors() {
connectionsTable.refreshTracTracConnectionList(); connectionsTable.refreshTracTracConnectionList();
raceList.getList().clear();
} }
@Override @Override
@@ -1678,7 +1678,7 @@ seriesHeaderUpcoming=Upcoming
eventRegattaLeaderboardLastScoreUpdate=Last Score Update eventRegattaLeaderboardLastScoreUpdate=Last Score Update
eventRegattaRaceNotTracked=Not Tracked eventRegattaRaceNotTracked=Not Tracked
footerJobs=Jobs footerJobs=Jobs
footerCopyright=\u00A9 2011-2022 SAP Sailing Analytics footerCopyright=\u00A9 2011-2023 SAP Sailing Analytics
footerLanguage=SAP Sailing in footerLanguage=SAP Sailing in
footerLegal=Legal Disclosure footerLegal=Legal Disclosure
footerPrivacy=Privacy footerPrivacy=Privacy
@@ -2449,4 +2449,4 @@ oneAlwaysStaysOne=Score 1 stays 1, regardless the column factor
otherTieBreakingLeaderboard=Other tie-breaking leaderboard otherTieBreakingLeaderboard=Other tie-breaking leaderboard
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=High Point System, Match Racing, Tie-Break Based on other Leaderboard scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=High Point System, Match Racing, Tie-Break Based on other Leaderboard
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=The winner of a race gets 1 point, all others 0; ties are broken on last race, then based on another leaderboard scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=The winner of a race gets 1 point, all others 0; ties are broken on last race, then based on another leaderboard
helptextLinkingRaces=In order to link races to tracked races, you must left-click a race in the table below and after that left-click the corresponding entry in the tracked races table on the right. helptextLinkingRaces=In order to link races to tracked races, you must left-click a race in the table below and after that left-click the corresponding entry in the tracked races table on the right.
@@ -42,7 +42,6 @@ boats=Lodě
competitorWithBoat=Závodník s lodí competitorWithBoat=Závodník s lodí
noSuchLeaderboard=Žádná taková výsledková tabule noSuchLeaderboard=Žádná taková výsledková tabule
leaderboardConfiguration=Konfigurace výsledkové tabule leaderboardConfiguration=Konfigurace výsledkové tabule
newDotDotDot=New...
editScores=Upravit body... editScores=Upravit body...
columnNamesInSelectedLeaderboard=Názvy rozjížděk na vybrané výsledkové tabuli columnNamesInSelectedLeaderboard=Názvy rozjížděk na vybrané výsledkové tabuli
addDotDotDot=Přidat... addDotDotDot=Přidat...
@@ -181,7 +180,6 @@ gapToLeaderLong=Ztráta na vedoucího závodníka
pointsToLoad=Body k načtení pointsToLoad=Body k načtení
speed=Rychlost speed=Rychlost
distance=Vzdálenost distance=Vzdálenost
in=in
secondsUnit=s secondsUnit=s
secondsPerNauticalMileUnit=s/NM secondsPerNauticalMileUnit=s/NM
metersUnit=m metersUnit=m
@@ -402,7 +400,6 @@ addFleet=Přidat flotilu
doYouReallyWantToRemoveRegatta=Chcete opravdu odebrat regatu „{0}“? Odeberou se také všechny výsledkové tabule pro tuto regatu! doYouReallyWantToRemoveRegatta=Chcete opravdu odebrat regatu „{0}“? Odeberou se také všechny výsledkové tabule pro tuto regatu!
errorLoadingScoreCorrectionProviders=Chyba při načítání poskytovatelů opravy bodů: {0} errorLoadingScoreCorrectionProviders=Chyba při načítání poskytovatelů opravy bodů: {0}
selectResultListToImportFrom=Vyberte seznam výsledků, ze kterého se má provést import selectResultListToImportFrom=Vyberte seznam výsledků, ze kterého se má provést import
of=of
errorObtainingScoreCorrections=Došlo k chybě při získávání oprav bodů od poskytovatele {0} a z události {1} pro lodní třídu {2}, publikování {3}: {4} errorObtainingScoreCorrections=Došlo k chybě při získávání oprav bodů od poskytovatele {0} a z události {1} pro lodní třídu {2}, publikování {3}: {4}
assignRaceNumbersToRaceColumns=Přiřadit čísla rozjížděk oficiálních výsledků sloupcům rozjížděk výsledkové tabule assignRaceNumbersToRaceColumns=Přiřadit čísla rozjížděk oficiálních výsledků sloupcům rozjížděk výsledkové tabule
importOfficialResults=Importování oficiálních výsledků... importOfficialResults=Importování oficiálních výsledků...
@@ -769,9 +766,6 @@ show=Zobrazit
hide=skrýt hide=skrýt
leftWind=Vítr zleva leftWind=Vítr zleva
rightWind=Vítr zprava rightWind=Vítr zprava
strategyOption1=strategyOption1
strategyOption2=strategyOption2
strategyOption3=strategyOption3
legLabel=Úsek legLabel=Úsek
raceLabel=Rozjížďka raceLabel=Rozjížďka
competitorLabel=Závodník competitorLabel=Závodník
@@ -1044,8 +1038,6 @@ rerunQueryAfterRefreshTooltip=Spustí dotaz znovu po aktualizaci tabulek.
releaseNotes=Novinky a historie verzí releaseNotes=Novinky a historie verzí
pwaAnchor=Přepnout na zobrazení PWA pwaAnchor=Přepnout na zobrazení PWA
hasSplitFleetContiguousScoring=Rozdělit flotily bodované průběžně hasSplitFleetContiguousScoring=Rozdělit flotily bodované průběžně
addRaceLogTracker=Add RaceLog Tracker
addRaceLogTrackers=Add RaceLog Trackers
denoteForRaceLogTracking=Denote for RaceLog tracking denoteForRaceLogTracking=Denote for RaceLog tracking
startRaceLogTracking=Start RaceLog Tracking startRaceLogTracking=Start RaceLog Tracking
filterByLeaderboard=Filtrovat podle výsledkové tabule filterByLeaderboard=Filtrovat podle výsledkové tabule
@@ -2451,3 +2443,4 @@ oneAlwaysStaysOne=Skóre 1 zůstane 1, bez ohledu na koeficient sloupce
otherTieBreakingLeaderboard=Jiná výsledková tabule pořadí při shodě otherTieBreakingLeaderboard=Jiná výsledková tabule pořadí při shodě
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Vysokobodový systém, souboj, shoda založená na jiné výsledkové tabuli scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Vysokobodový systém, souboj, shoda založená na jiné výsledkové tabuli
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Vítěz závodu získává 1 bod, všichni ostatní 0; při shodě rozhoduje poslední rozjížďka, potom údaje jiné výsledkové tabule. scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Vítěz závodu získává 1 bod, všichni ostatní 0; při shodě rozhoduje poslední rozjížďka, potom údaje jiné výsledkové tabule.
helptextLinkingRaces=Chcete-li propojit rozjížďky s trasovanými rozjížďkami, musíte kliknout levým tlačítkem na rozjížďku v tabulce níže a poté klikněte levým tlačítkem na odpovídající záznam v tabulce trasovaných rozjížděk vpravo.
@@ -400,7 +400,6 @@ addFleet=Tilføj flåde
doYouReallyWantToRemoveRegatta=Er du sikker på, at du vil fjerne regattaen "{0}"? Dette vil også fjerne alle ranglister for denne regatta! doYouReallyWantToRemoveRegatta=Er du sikker på, at du vil fjerne regattaen "{0}"? Dette vil også fjerne alle ranglister for denne regatta!
errorLoadingScoreCorrectionProviders=Fejl ved indlæsning af pointkorrektionsudbydere: {0} errorLoadingScoreCorrectionProviders=Fejl ved indlæsning af pointkorrektionsudbydere: {0}
selectResultListToImportFrom=Vælg resultatliste at importere fra selectResultListToImportFrom=Vælg resultatliste at importere fra
of=af
errorObtainingScoreCorrections=Fejl ved hentning af pointkorrektioner fra udbyder {0} og begivenhed {1} for bådklasse {2} publiceret den {3}: {4} errorObtainingScoreCorrections=Fejl ved hentning af pointkorrektioner fra udbyder {0} og begivenhed {1} for bådklasse {2} publiceret den {3}: {4}
assignRaceNumbersToRaceColumns=Tildel kapsejladsnumre for officielle resultater til kapsejladskolonner i ranglisten assignRaceNumbersToRaceColumns=Tildel kapsejladsnumre for officielle resultater til kapsejladskolonner i ranglisten
importOfficialResults=Importer officielle resultater... importOfficialResults=Importer officielle resultater...
@@ -767,9 +766,6 @@ show=Vis
hide=skjul hide=skjul
leftWind=Bagbord halse leftWind=Bagbord halse
rightWind=Styrbord halse rightWind=Styrbord halse
strategyOption1=strategyOption1
strategyOption2=strategyOption2
strategyOption3=strategyOption3
legLabel=Ben legLabel=Ben
raceLabel=Kapsejlads raceLabel=Kapsejlads
competitorLabel=Deltager competitorLabel=Deltager
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=Forstagstryk
currentDeflectorPercentageTooltip=Procentsats for deflektor currentDeflectorPercentageTooltip=Procentsats for deflektor
currentDeflectorInMillimetersTooltip=Deflektorafstand currentDeflectorInMillimetersTooltip=Deflektorafstand
currentTackAngleInDegreesTooltip=Den beregnede optimale stagvendingsvinkel currentTackAngleInDegreesTooltip=Den beregnede optimale stagvendingsvinkel
currentSetTooltip=Strøm (???) currentSetTooltip=Aktuel indstilling
currentRudderInDegreesTooltip=Rorvinkel. Negative værdier betyder til bagbord side, positive til styrbord side currentRudderInDegreesTooltip=Rorvinkel. Negative værdier betyder til bagbord side, positive til styrbord side
currentLeewayInDegreesTooltip=Afdrift currentLeewayInDegreesTooltip=Afdrift
currentDriftInDegreesTooltip=Vinkel mellem pejling og kurs over grunden currentDriftInDegreesTooltip=Vinkel mellem pejling og kurs over grunden
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=Score 1 ophold 1, uanset kolonnefaktor
otherTieBreakingLeaderboard=Anden afgørende rangliste otherTieBreakingLeaderboard=Anden afgørende rangliste
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Højpointsystem, matchracing, tie-break baseret på anden rangliste scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Højpointsystem, matchracing, tie-break baseret på anden rangliste
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Vinderen af en kapsejlads får 1 point, alle andre 0 point; uafgjort kapsejladser afgøres ved sidste løb og derefter på grundlag af en anden rangliste scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Vinderen af en kapsejlads får 1 point, alle andre 0 point; uafgjort kapsejladser afgøres ved sidste løb og derefter på grundlag af en anden rangliste
helptextLinkingRaces=For at knytte kapsejladser til sporede kapsejladser skal du venstreklikke på en kapsejlads i tabellen nedenfor og derefter venstreklikke på den tilhørende entry i tabellen for sporede kapsejladser i højre side.
@@ -400,7 +400,6 @@ addFleet=Añadir flota
doYouReallyWantToRemoveRegatta=¿Realmente desea eliminar la regata "{0}"? Con ello también se eliminarán todas las tablas de clasificación de esta regata. doYouReallyWantToRemoveRegatta=¿Realmente desea eliminar la regata "{0}"? Con ello también se eliminarán todas las tablas de clasificación de esta regata.
errorLoadingScoreCorrectionProviders=Error al cargar proveedores de corrección de puntuaciones: {0} errorLoadingScoreCorrectionProviders=Error al cargar proveedores de corrección de puntuaciones: {0}
selectResultListToImportFrom=Seleccione la lista de resultados desde la que desea importar selectResultListToImportFrom=Seleccione la lista de resultados desde la que desea importar
of=de
errorObtainingScoreCorrections=Error al obtener correcciones de puntuación del proveedor {0} y el evento {1} para la clase de embarcación {2} publicadas el {3}: {4} errorObtainingScoreCorrections=Error al obtener correcciones de puntuación del proveedor {0} y el evento {1} para la clase de embarcación {2} publicadas el {3}: {4}
assignRaceNumbersToRaceColumns=Asignar números de prueba de resultados oficiales a columnas de prueba de la tabla de clasificación assignRaceNumbersToRaceColumns=Asignar números de prueba de resultados oficiales a columnas de prueba de la tabla de clasificación
importOfficialResults=Importar resultados oficiales... importOfficialResults=Importar resultados oficiales...
@@ -767,9 +766,6 @@ show=Mostrar
hide=Ocultar hide=Ocultar
leftWind=Viento izquierdo leftWind=Viento izquierdo
rightWind=Viento derecho rightWind=Viento derecho
strategyOption1=strategyOption1
strategyOption2=strategyOption2
strategyOption3=strategyOption3
legLabel=Tramo legLabel=Tramo
raceLabel=Prueba raceLabel=Prueba
competitorLabel=Competidor competitorLabel=Competidor
@@ -1798,7 +1794,7 @@ errorLoadingRaceNames=Error al leer la información sobre las pruebas {0}
errorLoadingCompetitors=Error al leer la información sobre el competidor {0} errorLoadingCompetitors=Error al leer la información sobre el competidor {0}
errorLoadingTotalTime=Error al leer el tiempo total {0} errorLoadingTotalTime=Error al leer el tiempo total {0}
errorUpdatingCarriedPoints=Error al intentar actualizar el valor de transporte para el competidor {0} en la tabla de clasificación {1}: {2} \nEs posible que tenga que refrescar la vista. errorUpdatingCarriedPoints=Error al intentar actualizar el valor de transporte para el competidor {0} en la tabla de clasificación {1}: {2} \nEs posible que tenga que refrescar la vista.
errorUpdatingLeaderboardScore=Error al intentar actualizar la corrección de puntuación para el competidor {0} en la tabla de clasificación {1} para la prueba {2}: {3} \nEs posible que tenga que refrescar la vista. errorUpdatingLeaderboardScore=Error al intentar actualizar la corrección de puntuación para el competidor {0} en la tabla de clasificación {1} para la prueba {2}: {3} \nEs posible que tenga que actualizar la vista.
errorUpdatingLeaderboardScoreCorrection=Error al intentar actualizar la corrección de puntuación para: {0} \nEs posible que tenga que refrescar la vista. errorUpdatingLeaderboardScoreCorrection=Error al intentar actualizar la corrección de puntuación para: {0} \nEs posible que tenga que refrescar la vista.
errorUpdatingMaxPointsReason=Error al intentar actualizar la razón de puntos máximos para el competidor {0} en la tabla de clasificación {1} : {2} \nEs posible que tenga que refrescar la vista. errorUpdatingMaxPointsReason=Error al intentar actualizar la razón de puntos máximos para el competidor {0} en la tabla de clasificación {1} : {2} \nEs posible que tenga que refrescar la vista.
errorUpdatingDisplayNames=Error al intentar actualizar el nombre de visualización para el competidor {0} en la tabla de clasificación {1}: {2} \nEs posible que tenga que refrescar la vista. errorUpdatingDisplayNames=Error al intentar actualizar el nombre de visualización para el competidor {0} en la tabla de clasificación {1}: {2} \nEs posible que tenga que refrescar la vista.
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=Presión de estay de proa
currentDeflectorPercentageTooltip=Porcentaje de deflector currentDeflectorPercentageTooltip=Porcentaje de deflector
currentDeflectorInMillimetersTooltip=Distancia de deflector currentDeflectorInMillimetersTooltip=Distancia de deflector
currentTackAngleInDegreesTooltip=El ángulo de bordo óptimo calculado currentTackAngleInDegreesTooltip=El ángulo de bordo óptimo calculado
currentSetTooltip=Conjunto (???) currentSetTooltip=Opción actual
currentRudderInDegreesTooltip=Ángulo de timón; valores negativos significan a puerto; positivos, a estribor currentRudderInDegreesTooltip=Ángulo de timón; valores negativos significan a puerto; positivos, a estribor
currentLeewayInDegreesTooltip=Deriva currentLeewayInDegreesTooltip=Deriva
currentDriftInDegreesTooltip=Ángulo entre dirección y rumbo sobre fondo currentDriftInDegreesTooltip=Ángulo entre dirección y rumbo sobre fondo
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=La puntuación 1 se queda en 1 independientemente del factor d
otherTieBreakingLeaderboard=Otra tabla de clasificación de desempate otherTieBreakingLeaderboard=Otra tabla de clasificación de desempate
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema de puntuación alta, match racing, desempate en base a otra tabla de clasificación scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema de puntuación alta, match racing, desempate en base a otra tabla de clasificación
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=El ganador de una prueba obtiene 1 punto, todos los demás 0; se desempata en la última prueba, y luego se basan en otra tabla de clasificación scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=El ganador de una prueba obtiene 1 punto, todos los demás 0; se desempata en la última prueba, y luego se basan en otra tabla de clasificación
helptextLinkingRaces=Con el fin de enlazar las pruebas con las pruebas rastreadas, debe hacer clic con el botón izquierdo del ratón en una prueba de la tabla siguiente y, a continuación, hacer clic con el botón izquierdo del ratón en la entrada correspondiente de la tabla de pruebas rastreadas de la derecha.
@@ -400,7 +400,6 @@ addFleet=Ajouter flotte
doYouReallyWantToRemoveRegatta=Voulez-vous vraiment supprimer la régate "{0}" ? Cela entraînera également la suppression de tous les palmarès de cette régate. doYouReallyWantToRemoveRegatta=Voulez-vous vraiment supprimer la régate "{0}" ? Cela entraînera également la suppression de tous les palmarès de cette régate.
errorLoadingScoreCorrectionProviders=Erreur lors du chargement des fournisseurs de corrections de scores : {0} errorLoadingScoreCorrectionProviders=Erreur lors du chargement des fournisseurs de corrections de scores : {0}
selectResultListToImportFrom=Sélectionner la liste des résultats depuis laquelle importer selectResultListToImportFrom=Sélectionner la liste des résultats depuis laquelle importer
of=de
errorObtainingScoreCorrections=Erreur lors de l''accès aux corrections de scores du fournisseur {0} et manifestation {1} pour la catégorie de bateau {2} publié le {3}: {4} errorObtainingScoreCorrections=Erreur lors de l''accès aux corrections de scores du fournisseur {0} et manifestation {1} pour la catégorie de bateau {2} publié le {3}: {4}
assignRaceNumbersToRaceColumns=Affecter numéros de courses des résultats officiels aux colonnes de courses de palmarès assignRaceNumbersToRaceColumns=Affecter numéros de courses des résultats officiels aux colonnes de courses de palmarès
importOfficialResults=Importer résultats officiels... importOfficialResults=Importer résultats officiels...
@@ -767,9 +766,6 @@ show=Afficher
hide=Masquer hide=Masquer
leftWind=Vent de gauche leftWind=Vent de gauche
rightWind=Vent de droite rightWind=Vent de droite
strategyOption1=Option de stratégie 1
strategyOption2=Option de stratégie 2
strategyOption3=Option de stratégie 3
legLabel=Portion de parcours legLabel=Portion de parcours
raceLabel=Course raceLabel=Course
competitorLabel=Concurrent competitorLabel=Concurrent
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=Pression étai avant
currentDeflectorPercentageTooltip=Pourcentage déflecteur currentDeflectorPercentageTooltip=Pourcentage déflecteur
currentDeflectorInMillimetersTooltip=Distance déflecteur currentDeflectorInMillimetersTooltip=Distance déflecteur
currentTackAngleInDegreesTooltip=Angle de virement optimal calculé currentTackAngleInDegreesTooltip=Angle de virement optimal calculé
currentSetTooltip=Direction du courant (???) currentSetTooltip=Option actuelle
currentRudderInDegreesTooltip=Angle du gouvernail : valeurs négatives = à bâbord, valeurs positives = à tribord currentRudderInDegreesTooltip=Angle du gouvernail : valeurs négatives = à bâbord, valeurs positives = à tribord
currentLeewayInDegreesTooltip=Dérive currentLeewayInDegreesTooltip=Dérive
currentDriftInDegreesTooltip=Angle entre le cap et la route fond currentDriftInDegreesTooltip=Angle entre le cap et la route fond
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=Le score 1 reste 1 indépendamment du facteur de colonne.
otherTieBreakingLeaderboard=Autre palmarès pour départager les égalités otherTieBreakingLeaderboard=Autre palmarès pour départager les égalités
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Système de points avec bonus, Match racing, égalité départagée en fonction d''un autre palmarès scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Système de points avec bonus, Match racing, égalité départagée en fonction d''un autre palmarès
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Le vainqueur d''une course obtient 1 point, tous les autres participants 0 ; en cas d''égalité, l''égalité est départagée en fonction du résultat de la dernière course, puis en fonction d''un autre palmarès. scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Le vainqueur d''une course obtient 1 point, tous les autres participants 0 ; en cas d''égalité, l''égalité est départagée en fonction du résultat de la dernière course, puis en fonction d''un autre palmarès.
helptextLinkingRaces=Pour relier des courses à des courses suivies, vous devez sélectionner une course (clic gauche) dans la table ci-dessous puis sélectionner l''entrée correspondante (clic gauche) dans la table des courses suivies sur la droite.
@@ -400,7 +400,6 @@ addFleet=Aggiungi flotta
doYouReallyWantToRemoveRegatta=Confermare la rimozione della regata "{0}"? Questa azione rimuoverà anche tutte le classifiche di questa regata. doYouReallyWantToRemoveRegatta=Confermare la rimozione della regata "{0}"? Questa azione rimuoverà anche tutte le classifiche di questa regata.
errorLoadingScoreCorrectionProviders=Errore di caricamento dei provider di correzione dei punteggi: {0} errorLoadingScoreCorrectionProviders=Errore di caricamento dei provider di correzione dei punteggi: {0}
selectResultListToImportFrom=Seleziona l''elenco di risultati da cui eseguire l''importazione selectResultListToImportFrom=Seleziona l''elenco di risultati da cui eseguire l''importazione
of=di
errorObtainingScoreCorrections=Errore nell''ottenimento delle correzioni dei punteggi dal provider {0} e dall''evento {1} per la classe di barche {2} pubblicate il {3}: {4} errorObtainingScoreCorrections=Errore nell''ottenimento delle correzioni dei punteggi dal provider {0} e dall''evento {1} per la classe di barche {2} pubblicate il {3}: {4}
assignRaceNumbersToRaceColumns=Assegna numeri di gara dei risultati ufficiali alle colonne della gara in classifica assignRaceNumbersToRaceColumns=Assegna numeri di gara dei risultati ufficiali alle colonne della gara in classifica
importOfficialResults=Importa risultati ufficiali... importOfficialResults=Importa risultati ufficiali...
@@ -767,9 +766,6 @@ show=Mostra
hide=nascondi hide=nascondi
leftWind=Vento a sinistra leftWind=Vento a sinistra
rightWind=Vento a destra rightWind=Vento a destra
strategyOption1=opzioneStrategia1
strategyOption2=opzioneStrategia2
strategyOption3=opzioneStrategia3
legLabel=Tratta legLabel=Tratta
raceLabel=Gara raceLabel=Gara
competitorLabel=Concorrente competitorLabel=Concorrente
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=Pressione strallo
currentDeflectorPercentageTooltip=Percentuale deflettore currentDeflectorPercentageTooltip=Percentuale deflettore
currentDeflectorInMillimetersTooltip=Distanza deflettore currentDeflectorInMillimetersTooltip=Distanza deflettore
currentTackAngleInDegreesTooltip=L’angolo di virata ottimale calcolato currentTackAngleInDegreesTooltip=L’angolo di virata ottimale calcolato
currentSetTooltip=Set (???) currentSetTooltip=Impostazione corrente
currentRudderInDegreesTooltip=Angolo timone; valore negativo a sinistra, positivo a dritta currentRudderInDegreesTooltip=Angolo timone; valore negativo a sinistra, positivo a dritta
currentLeewayInDegreesTooltip=Scarroccio currentLeewayInDegreesTooltip=Scarroccio
currentDriftInDegreesTooltip=Angolo tra angolo di rotta e rotta effettiva currentDriftInDegreesTooltip=Angolo tra angolo di rotta e rotta effettiva
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=Il punteggio 1 resta 1 a prescindere dal fattore della colonna
otherTieBreakingLeaderboard=Altra classifica di spareggio otherTieBreakingLeaderboard=Altra classifica di spareggio
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema di punteggio massimo, match race, spareggio basato su altra classifica scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema di punteggio massimo, match race, spareggio basato su altra classifica
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Il vincitore della gara ottiene 1 punto, tutti gli altri 0; i pareggi vengono risolti nell''ultima gara, quindi in base a un''altra classifica scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Il vincitore della gara ottiene 1 punto, tutti gli altri 0; i pareggi vengono risolti nell''ultima gara, quindi in base a un''altra classifica
helptextLinkingRaces=Per collegare le gare a quelle tracciate, è necessario fare clic con il pulsante sinistro del mouse su una gara nella tabella sottostante e, successivamente, fare clic con il pulsante sinistro del mouse sulla voce corrispondente nella tabella delle gare tracciate a destra.
@@ -400,7 +400,6 @@ addFleet=フリート追加
doYouReallyWantToRemoveRegatta=レガッタ "{0}" を削除しますか。削除すると、このレガッタのためのリーダーボードもすべて削除されます。 doYouReallyWantToRemoveRegatta=レガッタ "{0}" を削除しますか。削除すると、このレガッタのためのリーダーボードもすべて削除されます。
errorLoadingScoreCorrectionProviders=スコア修正プロバイダのロードでエラー発生: {0} errorLoadingScoreCorrectionProviders=スコア修正プロバイダのロードでエラー発生: {0}
selectResultListToImportFrom=インポート元の結果一覧を選択 selectResultListToImportFrom=インポート元の結果一覧を選択
of=of
errorObtainingScoreCorrections=プロバイダ {0} からのスコア修正および艇種 {2} のイベント {1} (公表日付 {3}) の取得でエラー発生: {4} errorObtainingScoreCorrections=プロバイダ {0} からのスコア修正および艇種 {2} のイベント {1} (公表日付 {3}) の取得でエラー発生: {4}
assignRaceNumbersToRaceColumns=公式結果のレース番号をリーダーボードのレース列に割り当ててください assignRaceNumbersToRaceColumns=公式結果のレース番号をリーダーボードのレース列に割り当ててください
importOfficialResults=公式結果をインポートしています... importOfficialResults=公式結果をインポートしています...
@@ -767,9 +766,6 @@ show=表示
hide=非表示 hide=非表示
leftWind=レフトウィンド leftWind=レフトウィンド
rightWind=ライトウィンド rightWind=ライトウィンド
strategyOption1=strategyOption1
strategyOption2=strategyOption2
strategyOption3=strategyOption3
legLabel=レグ legLabel=レグ
raceLabel=レース raceLabel=レース
competitorLabel=競技者 competitorLabel=競技者
@@ -1211,7 +1207,7 @@ advanced=予選通過
retrieveWith=検索キー retrieveWith=検索キー
mappingDetails=マッピング詳細 mappingDetails=マッピング詳細
deviceMappingQrCodeExplanation=追跡アプリを使用している場合は、競技者/マークを選択し、開始時刻と終了時刻を設定してから、この QRCode をスキャンすることによってデバイスマッピングも追加することができます。 deviceMappingQrCodeExplanation=追跡アプリを使用している場合は、競技者/マークを選択し、開始時刻と終了時刻を設定してから、この QRCode をスキャンすることによってデバイスマッピングも追加することができます。
qrCode=QRCode qrCode=QR コード
enterCourseAreaName=コース領域名を入力... enterCourseAreaName=コース領域名を入力...
enterCourseName=コース名を入力... enterCourseName=コース名を入力...
enterImageURL=画像 URL を入力... enterImageURL=画像 URL を入力...
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=フォアステイ圧
currentDeflectorPercentageTooltip=ディフレクター比 (%) currentDeflectorPercentageTooltip=ディフレクター比 (%)
currentDeflectorInMillimetersTooltip=ディフレクター距離 currentDeflectorInMillimetersTooltip=ディフレクター距離
currentTackAngleInDegreesTooltip=計算による最適タック角 currentTackAngleInDegreesTooltip=計算による最適タック角
currentSetTooltip=セット (???) currentSetTooltip=現在の設定
currentRudderInDegreesTooltip=ラダー角 (マイナス値は左舷、プラス値は右舷を意味) currentRudderInDegreesTooltip=ラダー角 (マイナス値は左舷、プラス値は右舷を意味)
currentLeewayInDegreesTooltip=リーウェイ currentLeewayInDegreesTooltip=リーウェイ
currentDriftInDegreesTooltip=針路と対地コースの間の角度 currentDriftInDegreesTooltip=針路と対地コースの間の角度
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=得点 1 は列係数に関係なく 1 点のまま
otherTieBreakingLeaderboard=タイブレークのための別リーダーボード otherTieBreakingLeaderboard=タイブレークのための別リーダーボード
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=高得点方式、マッチレース、別リーダーボードに基づくタイブレーク scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=高得点方式、マッチレース、別リーダーボードに基づくタイブレーク
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=レースの勝者が 1 点を獲得し、その他はすべて 0 点。同順位はまず最終レース、次に別リーダーボードに基づいてタイブレーク scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=レースの勝者が 1 点を獲得し、その他はすべて 0 点。同順位はまず最終レース、次に別リーダーボードに基づいてタイブレーク
helptextLinkingRaces=レースを追跡レースにリンクするためには、下の表でレースを左クリックしてから、右側の追跡レース表で該当するエントリを左クリックする必要があります。
@@ -400,7 +400,6 @@ addFleet=Adicionar flotilha
doYouReallyWantToRemoveRegatta=Você tem a certeza que quer remover a regata "{0}"? Isto irá remover também todos os painéis de classificação para esta regata! doYouReallyWantToRemoveRegatta=Você tem a certeza que quer remover a regata "{0}"? Isto irá remover também todos os painéis de classificação para esta regata!
errorLoadingScoreCorrectionProviders=Erro ao carregar fornecedores de correções de pontuação: {0} errorLoadingScoreCorrectionProviders=Erro ao carregar fornecedores de correções de pontuação: {0}
selectResultListToImportFrom=Selecionar lista de resultados de onde efetuar a importação selectResultListToImportFrom=Selecionar lista de resultados de onde efetuar a importação
of=de
errorObtainingScoreCorrections=Erro ao obter correções de pontuação do fornecedor {0} e evento {1} para classe de barcos {2} publicada em {3}: {4} errorObtainingScoreCorrections=Erro ao obter correções de pontuação do fornecedor {0} e evento {1} para classe de barcos {2} publicada em {3}: {4}
assignRaceNumbersToRaceColumns=Atribuir números da corrida de resultados oficiais a colunas da corrida do painel de classificação assignRaceNumbersToRaceColumns=Atribuir números da corrida de resultados oficiais a colunas da corrida do painel de classificação
importOfficialResults=Importar resultados oficiais... importOfficialResults=Importar resultados oficiais...
@@ -767,9 +766,6 @@ show=Visualizar
hide=ocultar hide=ocultar
leftWind=Vento da esquerda leftWind=Vento da esquerda
rightWind=Vento da direita rightWind=Vento da direita
strategyOption1=Opção 1 de estratégia
strategyOption2=Opção 2 de estratégia
strategyOption3=Opção 3 de estratégia
legLabel=Perna legLabel=Perna
raceLabel=Corrida raceLabel=Corrida
competitorLabel=Competidor competitorLabel=Competidor
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=Pressão de estai
currentDeflectorPercentageTooltip=Porcentagem de defletor currentDeflectorPercentageTooltip=Porcentagem de defletor
currentDeflectorInMillimetersTooltip=Distância de defletor currentDeflectorInMillimetersTooltip=Distância de defletor
currentTackAngleInDegreesTooltip=O ângulo de cambada ideal calculado currentTackAngleInDegreesTooltip=O ângulo de cambada ideal calculado
currentSetTooltip=Curso (???) currentSetTooltip=Configuração atual
currentRudderInDegreesTooltip=Ângulo do leme; valores negativos indicam bombordo, positivos boreste currentRudderInDegreesTooltip=Ângulo do leme; valores negativos indicam bombordo, positivos boreste
currentLeewayInDegreesTooltip=Abatimento currentLeewayInDegreesTooltip=Abatimento
currentDriftInDegreesTooltip=Ângulo entre orientação e percurso no fundo currentDriftInDegreesTooltip=Ângulo entre orientação e percurso no fundo
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=A pontuação 1 fica 1, independentemente do fator da coluna
otherTieBreakingLeaderboard=Outro painel de classificação de tie-break otherTieBreakingLeaderboard=Outro painel de classificação de tie-break
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema de bônus, "Match Racing", tie-break com base noutro painel de classificação scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Sistema de bônus, "Match Racing", tie-break com base noutro painel de classificação
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=O vencedor de uma corrida obtém 1 ponto, todos os outros 0; os desempates são efetuados com base na última corrida, depois com base noutro painel de classificação scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=O vencedor de uma corrida obtém 1 ponto, todos os outros 0; os desempates são efetuados com base na última corrida, depois com base noutro painel de classificação
helptextLinkingRaces=Para vincular corridas a corridas rastreadas, deve clicar com o botão esquerdo em uma corrida na tabela embaixo e depois disso clicar com o botão esquerdo na entrada correspondente na tabela de corridas rastreadas à direita.
@@ -400,7 +400,6 @@ addFleet=Добавить флот
doYouReallyWantToRemoveRegatta=Действительно удалить регату "{0}"? При этом также будут удалены все таблицы лидеров для данной регаты! doYouReallyWantToRemoveRegatta=Действительно удалить регату "{0}"? При этом также будут удалены все таблицы лидеров для данной регаты!
errorLoadingScoreCorrectionProviders=Ошибка при загрузке поставщиков корректировки оценок: {0} errorLoadingScoreCorrectionProviders=Ошибка при загрузке поставщиков корректировки оценок: {0}
selectResultListToImportFrom=Выберите список результатов для импорта selectResultListToImportFrom=Выберите список результатов для импорта
of=из
errorObtainingScoreCorrections=Ошибка при получении корректировок оценок от поставщика {0} и события {1} для класса лодок {2}, опубликованных в {3}: {4} errorObtainingScoreCorrections=Ошибка при получении корректировок оценок от поставщика {0} и события {1} для класса лодок {2}, опубликованных в {3}: {4}
assignRaceNumbersToRaceColumns=Присвойте номера гонок официальных результатов столбцам гонок таблицы лидеров assignRaceNumbersToRaceColumns=Присвойте номера гонок официальных результатов столбцам гонок таблицы лидеров
importOfficialResults=Импорт официальных результатов... importOfficialResults=Импорт официальных результатов...
@@ -767,9 +766,6 @@ show=Показать
hide=скрыть hide=скрыть
leftWind=Ветер слева leftWind=Ветер слева
rightWind=Ветер справа rightWind=Ветер справа
strategyOption1=strategyOption1
strategyOption2=strategyOption2
strategyOption3=strategyOption3
legLabel=Отрезок legLabel=Отрезок
raceLabel=Гонка raceLabel=Гонка
competitorLabel=Участник competitorLabel=Участник
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=Давление форштага
currentDeflectorPercentageTooltip=Процент отражателя currentDeflectorPercentageTooltip=Процент отражателя
currentDeflectorInMillimetersTooltip=Дистанция для отражателя currentDeflectorInMillimetersTooltip=Дистанция для отражателя
currentTackAngleInDegreesTooltip=Расчетный оптимальный галсовый угол currentTackAngleInDegreesTooltip=Расчетный оптимальный галсовый угол
currentSetTooltip=Направление течения (???) currentSetTooltip=Текущая настройка
currentRudderInDegreesTooltip=Угол отклонения руля; отрицательные значения означают отклонение по левому борту, положительные - отклонение по правому currentRudderInDegreesTooltip=Угол отклонения руля; отрицательные значения означают отклонение по левому борту, положительные - отклонение по правому
currentLeewayInDegreesTooltip=Боковой снос currentLeewayInDegreesTooltip=Боковой снос
currentDriftInDegreesTooltip=Угол между направлением и курсом лодки относительно земли currentDriftInDegreesTooltip=Угол между направлением и курсом лодки относительно земли
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=Балл 1 остается 1 независимо от коэ
otherTieBreakingLeaderboard=Другая таблица лидеров с равенством otherTieBreakingLeaderboard=Другая таблица лидеров с равенством
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Система высоких баллов, матчевая гонка, равенство на основе другой таблицы лидеров scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Система высоких баллов, матчевая гонка, равенство на основе другой таблицы лидеров
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Победитель гонки получает 1 балл, остальные 0; при равенстве баллов победитель определяется в последней гонке, а затем на основе другой таблица лидеров scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Победитель гонки получает 1 балл, остальные 0; при равенстве баллов победитель определяется в последней гонке, а затем на основе другой таблица лидеров
helptextLinkingRaces=Чтобы соединить гонки с отслеживаемыми гонками, щелкните левой клавишей мыши гонку в таблице и после этого щелкните левой клавишей мыши соответствующую запись в таблице отслеживаемых гонок справа.
@@ -400,7 +400,6 @@ addFleet=Dodaj floto
doYouReallyWantToRemoveRegatta=Ali res želite odstraniti regato "{0}"? S tem boste odstranili tudi vse lestvice vodilnih za to regato. doYouReallyWantToRemoveRegatta=Ali res želite odstraniti regato "{0}"? S tem boste odstranili tudi vse lestvice vodilnih za to regato.
errorLoadingScoreCorrectionProviders=Napaka pri nalaganju ponudnikov popravkov rezultatov: {0} errorLoadingScoreCorrectionProviders=Napaka pri nalaganju ponudnikov popravkov rezultatov: {0}
selectResultListToImportFrom=Izberite seznam rezultatov za uvoz iz selectResultListToImportFrom=Izberite seznam rezultatov za uvoz iz
of=od
errorObtainingScoreCorrections=Napaka pri pridobivanju popravkov rezultatov od ponudnika {0} in dogodka {1} za kategorijo jadrnice {2}, objavljeno {3}: {4} errorObtainingScoreCorrections=Napaka pri pridobivanju popravkov rezultatov od ponudnika {0} in dogodka {1} za kategorijo jadrnice {2}, objavljeno {3}: {4}
assignRaceNumbersToRaceColumns=Dodeli številke plovov z uradnimi rezultati stolpcem plovov z lestvicami vodilnih assignRaceNumbersToRaceColumns=Dodeli številke plovov z uradnimi rezultati stolpcem plovov z lestvicami vodilnih
importOfficialResults=Uvozi uradne rezultate ... importOfficialResults=Uvozi uradne rezultate ...
@@ -767,9 +766,6 @@ show=Pokaži
hide=Skrij hide=Skrij
leftWind=Veter z leve leftWind=Veter z leve
rightWind=Veter z desne rightWind=Veter z desne
strategyOption1=možnost strategije 1
strategyOption2=možnost strategije 2
strategyOption3=možnost strategije 3
legLabel=Stranica legLabel=Stranica
raceLabel=Plov raceLabel=Plov
competitorLabel=Tekmovalec competitorLabel=Tekmovalec
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=Pritisk na napono
currentDeflectorPercentageTooltip=Odstotek deflektorja currentDeflectorPercentageTooltip=Odstotek deflektorja
currentDeflectorInMillimetersTooltip=Razdalja deflektorja currentDeflectorInMillimetersTooltip=Razdalja deflektorja
currentTackAngleInDegreesTooltip=Izračunani optimalni kot prečenja currentTackAngleInDegreesTooltip=Izračunani optimalni kot prečenja
currentSetTooltip=Umirjanje (???) currentSetTooltip=Aktualna nastavitev
currentRudderInDegreesTooltip=Kot krmila; negativne vrednosti pomenijo v levo, pozitivne pa v desno stran currentRudderInDegreesTooltip=Kot krmila; negativne vrednosti pomenijo v levo, pozitivne pa v desno stran
currentLeewayInDegreesTooltip=Odklon currentLeewayInDegreesTooltip=Odklon
currentDriftInDegreesTooltip=Kot med smerjo in kurzom preko dna currentDriftInDegreesTooltip=Kot med smerjo in kurzom preko dna
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=Rezultat 1 ostane 1 ne glede na faktor stolpca
otherTieBreakingLeaderboard=Druga lestvica vodilnih z neodločenim rezultatom otherTieBreakingLeaderboard=Druga lestvica vodilnih z neodločenim rezultatom
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Napredno točkovanje, regatni dvoboj, neodločen rezultat na osnovi druge lestvice vodilnih scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=Napredno točkovanje, regatni dvoboj, neodločen rezultat na osnovi druge lestvice vodilnih
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Zmagovalec plova prejme 1 točko, vsi ostali 0 točk; v primeru neodločenega rezultata odloča zadnji plov, nato pa na podlagi druge lestvice vodilnih scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=Zmagovalec plova prejme 1 točko, vsi ostali 0 točk; v primeru neodločenega rezultata odloča zadnji plov, nato pa na podlagi druge lestvice vodilnih
helptextLinkingRaces=Če želite plove povezati s sledenimi plovi, morate z levim gumbom miške klikniti plov v spodnji tabeli in nato ustrezen vnos v tabeli sledenih plovov na desni.
@@ -400,7 +400,6 @@ addFleet=添加船队
doYouReallyWantToRemoveRegatta=是否确定移除比赛 "{0}"?还将移除此比赛的所有积分榜! doYouReallyWantToRemoveRegatta=是否确定移除比赛 "{0}"?还将移除此比赛的所有积分榜!
errorLoadingScoreCorrectionProviders=加载得分更正机构出错: {0} errorLoadingScoreCorrectionProviders=加载得分更正机构出错: {0}
selectResultListToImportFrom=选择从中导入的结果清单 selectResultListToImportFrom=选择从中导入的结果清单
of=/
errorObtainingScoreCorrections=从机构{0}获取于{3}公布的船只级别{2}活动{1}的得分更正出错: {4} errorObtainingScoreCorrections=从机构{0}获取于{3}公布的船只级别{2}活动{1}的得分更正出错: {4}
assignRaceNumbersToRaceColumns=向积分榜比赛轮次列分配官方结果的比赛轮次数 assignRaceNumbersToRaceColumns=向积分榜比赛轮次列分配官方结果的比赛轮次数
importOfficialResults=导入官方结果... importOfficialResults=导入官方结果...
@@ -767,9 +766,6 @@ show=显示
hide=隐藏 hide=隐藏
leftWind=左侧风 leftWind=左侧风
rightWind=右侧风 rightWind=右侧风
strategyOption1=策略选项 1
strategyOption2=策略选项 2
strategyOption3=策略选项 3
legLabel=航段 legLabel=航段
raceLabel=比赛轮次 raceLabel=比赛轮次
competitorLabel=参赛队 competitorLabel=参赛队
@@ -1932,7 +1928,7 @@ currentForestayPressureTooltip=前桅支索压力
currentDeflectorPercentageTooltip=转向器百分比 currentDeflectorPercentageTooltip=转向器百分比
currentDeflectorInMillimetersTooltip=转向器距离 currentDeflectorInMillimetersTooltip=转向器距离
currentTackAngleInDegreesTooltip=计算的最佳迎风转向角度 currentTackAngleInDegreesTooltip=计算的最佳迎风转向角度
currentSetTooltip=扬帆 (???) currentSetTooltip=当前设置
currentRudderInDegreesTooltip=舵角;负值表示左舵,正值表示右舵 currentRudderInDegreesTooltip=舵角;负值表示左舵,正值表示右舵
currentLeewayInDegreesTooltip=航差角 currentLeewayInDegreesTooltip=航差角
currentDriftInDegreesTooltip=航向与对地航向之间的角度 currentDriftInDegreesTooltip=航向与对地航向之间的角度
@@ -2447,3 +2443,4 @@ oneAlwaysStaysOne=不论列系数是多少,1 分始终为 1
otherTieBreakingLeaderboard=其他打破平局的积分榜 otherTieBreakingLeaderboard=其他打破平局的积分榜
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=高分系统,对抗赛,基于其他积分榜的决胜局 scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboard=高分系统,对抗赛,基于其他积分榜的决胜局
scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=比赛轮次的获胜者得 1 分,所有其他人得 0 分;在最后一个比赛轮次中打破平局,然后根据其他积分榜打破平局 scoringSchemeHighPointsByWindTiesLastlyBrokenByOtherLeaderboardDescription=比赛轮次的获胜者得 1 分,所有其他人得 0 分;在最后一个比赛轮次中打破平局,然后根据其他积分榜打破平局
helptextLinkingRaces=为了在比赛轮次之间建立链接,您必须左键点击下表中的比赛轮次,然后左键点击右侧跟踪比赛轮次表中的相应条目。
@@ -6192,7 +6192,9 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
@Override @Override
public Integer getAdminConsoleChangeLogSize() { public Integer getAdminConsoleChangeLogSize() {
try (CloseableHttpClient client = HttpClients.createDefault()) { try (CloseableHttpClient client = HttpClients.createDefault()) {
final URIBuilder url = new URIBuilder(getRequestBaseURL().toURI()).setPath("release_notes_admin.html"); // FIXME this will break for any reverse proxy or port-mapping container between the client and this server!
final int localPort = getThreadLocalRequest().getLocalPort();
final URIBuilder url = new URIBuilder("http://127.0.0.1:"+localPort+"/release_notes_admin.html");
final HttpGet request = new HttpGet(url.build()); final HttpGet request = new HttpGet(url.build());
return client.execute(request, response -> EntityUtils.toString(response.getEntity())).length(); return client.execute(request, response -> EntityUtils.toString(response.getEntity())).length();
} catch (IOException | URISyntaxException e) { } catch (IOException | URISyntaxException e) {
@@ -38,6 +38,7 @@ import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.impl.AwsApplicationProcessImpl; import com.sap.sse.landscape.aws.impl.AwsApplicationProcessImpl;
import com.sap.sse.landscape.impl.ReleaseImpl; import com.sap.sse.landscape.impl.ReleaseImpl;
import com.sap.sse.shared.util.Wait; import com.sap.sse.shared.util.Wait;
import com.sap.sse.util.HttpUrlConnectionHelper;
import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes; import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes;
public class SailingAnalyticsProcessImpl<ShardingKey> public class SailingAnalyticsProcessImpl<ShardingKey>
@@ -75,7 +76,8 @@ implements SailingAnalyticsProcess<ShardingKey> {
final HttpResponse result = client.execute(getStatusRequest); final HttpResponse result = client.execute(getStatusRequest);
final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final ByteArrayOutputStream bos = new ByteArrayOutputStream();
result.getEntity().writeTo(bos); result.getEntity().writeTo(bos);
return (JSONObject) (new JSONParser().parse(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray())))); return (JSONObject) (new JSONParser().parse(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray()),
HttpUrlConnectionHelper.getCharsetFromHttpEntity(result.getEntity(), "UTF-8"))));
}, json->json != null, /* retryOnException */ true, optionalTimeout, }, json->json != null, /* retryOnException */ true, optionalTimeout,
/* sleepBetweenAttempts */ Duration.ONE_SECOND.times(5), Level.INFO, "getStatus() on "+getHost()+":"+getPort()); /* sleepBetweenAttempts */ Duration.ONE_SECOND.times(5), Level.INFO, "getStatus() on "+getHost()+":"+getPort());
updateStartTimePointFromStatus(status); updateStartTimePointFromStatus(status);
@@ -7,5 +7,9 @@ import com.sap.sse.common.TimePoint;
public interface CsvParserFactory { public interface CsvParserFactory {
CsvParserFactory INSTANCE = new CsvParserFactoryImpl(); CsvParserFactory INSTANCE = new CsvParserFactoryImpl();
/**
* @param is expected to be encoded with the "cp1252" character set
*/
CsvParser createParser(InputStream is, String name, TimePoint lastModified); CsvParser createParser(InputStream is, String name, TimePoint lastModified);
} }
@@ -18,6 +18,10 @@ import com.sap.sailing.resultimport.impl.DefaultCompetitorEntryImpl;
import com.sap.sailing.sailwave.resultimport.CsvParser; import com.sap.sailing.sailwave.resultimport.CsvParser;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
/**
* Parses CSV files. The input stream passed to the constructor is expected to be encoded with the "cp1252"
* character set.
*/
public class CsvParserImpl implements CsvParser { public class CsvParserImpl implements CsvParser {
private final InputStream inputStream; private final InputStream inputStream;
@@ -4,6 +4,5 @@
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/> <classpathentry kind="src" path="resources"/>
<classpathentry exported="true" kind="lib" path="lib/cglib-nodep-2.2.3.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>
@@ -18,8 +18,7 @@ Require-Bundle: org.hamcrest;bundle-version="2.2.0",
org.mongodb.driver-sync;bundle-version="4.3.1", org.mongodb.driver-sync;bundle-version="4.3.1",
com.sun.jersey;bundle-version="1.17.0", com.sun.jersey;bundle-version="1.17.0",
com.sap.sse.security com.sap.sse.security
Bundle-ClassPath: lib/cglib-nodep-2.2.3.jar, Bundle-ClassPath: .
.
Automatic-Module-Name: com.sap.sailing.selenium.test Automatic-Module-Name: com.sap.sailing.selenium.test
Import-Package: javax.ws.rs.core;version="1.1.1", Import-Package: javax.ws.rs.core;version="1.1.1",
org.apache.http.client;version="4.5.5", org.apache.http.client;version="4.5.5",
@@ -3,5 +3,4 @@ source.. = src/,\
output.. = bin/ output.. = bin/
bin.includes = META-INF/,\ bin.includes = META-INF/,\
.,\ .,\
test-environment-configuration.xsd,\ test-environment-configuration.xsd
lib/cglib-nodep-2.2.3.jar
@@ -1,7 +1,5 @@
package com.sap.sailing.selenium.pages.adminconsole.leaderboard; package com.sap.sailing.selenium.pages.adminconsole.leaderboard;
import static com.sap.sailing.selenium.pages.gwt.query.Alias.$;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
@@ -12,8 +10,6 @@ import com.sap.sailing.selenium.pages.adminconsole.ActionsHelper;
import com.sap.sailing.selenium.pages.gwt.CellTablePO; import com.sap.sailing.selenium.pages.gwt.CellTablePO;
import com.sap.sailing.selenium.pages.gwt.DataEntryPO; import com.sap.sailing.selenium.pages.gwt.DataEntryPO;
import com.sap.sailing.selenium.pages.gwt.GenericCellTablePO; import com.sap.sailing.selenium.pages.gwt.GenericCellTablePO;
import com.sap.sailing.selenium.pages.gwt.query.Alias;
import com.sap.sailing.selenium.pages.gwt.query.TableQuery;
public class LeaderboardGroupConfigurationPanelPO extends PageArea { public class LeaderboardGroupConfigurationPanelPO extends PageArea {
@FindBy(how = BySeleniumId.class, using = "CreateLeaderboardGroupButton") @FindBy(how = BySeleniumId.class, using = "CreateLeaderboardGroupButton")
@@ -81,14 +77,7 @@ public class LeaderboardGroupConfigurationPanelPO extends PageArea {
} }
private DataEntryPO findLeaderboardGroup(String name) { private DataEntryPO findLeaderboardGroup(String name) {
CellTablePO<DataEntryPO> table = getLeaderboardGroupsTable(); final CellTablePO<DataEntryPO> table = getLeaderboardGroupsTable();
final DataEntryPO alias = Alias.alias(DataEntryPO.class); return table.getEntries().stream().filter(e->e.getColumnContent("Name").equals(name)).findFirst().orElse(null);
TableQuery<DataEntryPO> query = new TableQuery<>();
query.from(table)
.where(
$(alias.getColumnContent("Name")).eq(name)
);
return query.firstResult();
} }
} }
@@ -1,22 +1,15 @@
package com.sap.sailing.selenium.pages.adminconsole.leaderboard; package com.sap.sailing.selenium.pages.adminconsole.leaderboard;
import static com.sap.sailing.selenium.pages.gwt.query.Alias.$;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import com.sap.sailing.selenium.core.BySeleniumId; import com.sap.sailing.selenium.core.BySeleniumId;
import com.sap.sailing.selenium.core.FindBy; import com.sap.sailing.selenium.core.FindBy;
import com.sap.sailing.selenium.pages.PageArea; import com.sap.sailing.selenium.pages.PageArea;
import com.sap.sailing.selenium.pages.gwt.CellTablePO; import com.sap.sailing.selenium.pages.gwt.CellTablePO;
import com.sap.sailing.selenium.pages.gwt.DataEntryPO; import com.sap.sailing.selenium.pages.gwt.DataEntryPO;
import com.sap.sailing.selenium.pages.gwt.GenericCellTablePO; import com.sap.sailing.selenium.pages.gwt.GenericCellTablePO;
import com.sap.sailing.selenium.pages.gwt.query.Alias;
import com.sap.sailing.selenium.pages.gwt.query.TableQuery;
public class LeaderboardGroupDetailsPanelPO extends PageArea { public class LeaderboardGroupDetailsPanelPO extends PageArea {
@FindBy(how = BySeleniumId.class, using = "LeaderboardsFilterTextBox") @FindBy(how = BySeleniumId.class, using = "LeaderboardsFilterTextBox")
private WebElement leaderboardsFilterTextBox; private WebElement leaderboardsFilterTextBox;
@@ -40,14 +33,8 @@ public class LeaderboardGroupDetailsPanelPO extends PageArea {
} }
public DataEntryPO findLeaderboardEntry(String name) { public DataEntryPO findLeaderboardEntry(String name) {
CellTablePO<DataEntryPO> table = getLeaderboardsTable(); final CellTablePO<DataEntryPO> table = getLeaderboardsTable();
DataEntryPO alias = Alias.alias(DataEntryPO.class); return table.getEntries().stream().filter(e->e.getColumnContent("Leaderboard Name").equals(name)).findFirst().orElse(null);
TableQuery<DataEntryPO> query = new TableQuery<>();
query.from(table).
where($(alias.getColumnContent("Leaderboard Name")).eq(name));
return query.firstResult();
} }
public void filterLeaderboards(String filterText) { public void filterLeaderboards(String filterText) {
@@ -1,80 +0,0 @@
package com.sap.sailing.selenium.pages.gwt.query;
import com.sap.sailing.selenium.pages.gwt.query.path.BooleanPath;
import com.sap.sailing.selenium.pages.gwt.query.path.StringPath;
public class Alias {
private static final AliasFactory factory = new AliasFactory();
public static <A> A alias(Class<A> clazz) {
return factory.createAlias(clazz);
}
public static <D extends Expression<?>> D $() {
return factory.getCurrentExpressionAndReset();
}
public static StringPath $(String value) {
return $();
}
public static BooleanPath $(Boolean value) {
return $();
}
public static BooleanPath $(boolean value) {
return $();
}
// public static NumberPath $(Byte value) {
// return $();
// }
// public static NumberPath $(byte value) {
// return $();
// }
//
// public static NumberPath $(Short value) {
// return $();
// }
//
// public static NumberPath $(short value) {
// return $();
// }
//
// public static NumberPath $(Integer value) {
// return $();
// }
//
// public static NumberPath $(int value) {
// return $();
// }
//
// public static NumberPath $(Long value) {
// return $();
// }
//
// public static NumberPath $(long value) {
// return $();
// }
//
// public static NumberPath $(Float value) {
// return $();
// }
//
// public static NumberPath $(float value) {
// return $();
// }
//
// public static NumberPath $(Double value) {
// return $();
// }
//
// public static NumberPath $(double value) {
// return $();
// }
public static void resetAlias() {
factory.reset();
}
}
@@ -1,117 +0,0 @@
package com.sap.sailing.selenium.pages.gwt.query;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class AliasFactory {
public interface ManagedObject {
/**
* <p></p>
*
* @return
*
*/
/*Expression<?>*/ Object __mappedPath();
}
private class MethodAccessTracker implements MethodInterceptor {
private static final String TO_STRING = "toString";
private static final String HASH_CODE = "hashCode";
private static final String MAPPED_PATH = "__mappedPath";
private final Expression<?> hostExpression;
public MethodAccessTracker(Expression<?> host) {
this.hostExpression = host;
}
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
Class<?> returnType = method.getReturnType();
//Type genericReturnType = method.getGenericReturnType();
if(Modifier.isPublic(method.getModifiers())) {
if (MAPPED_PATH.equals(methodName) && parameterTypes.length == 0)
return this.hostExpression;
if (TO_STRING.equals(methodName) && parameterTypes.length == 0)
return this.hostExpression.toString();
if (HASH_CODE.equals(methodName) && parameterTypes.length == 0)
return Integer.valueOf(this.hostExpression.hashCode());
PathMetadata<?> metadata = getOrCreatePathMetadata(method, args);
Path<?> path = PathFactory.createPath(returnType, metadata);
AliasFactory.this.setCurrentExpression(path);
}
return null;
}
private PathMetadata<?> getOrCreatePathMetadata(Method method, Object[] args) {
return new PathMetadata<>((Path<?>) this.hostExpression, method, args);
}
}
private final ThreadLocal<Expression<?>> current = new ThreadLocal<>();
@SuppressWarnings("unchecked")
public <A extends Expression<?>> A getCurrentExpression() {
return (A) this.current.get();
}
/**
* <p>Returns the current thread bound expression and resets it.</p>
*
* @param <A>
*
* @return
* The current thread bound expression.
*/
public <A extends Expression<?>> A getCurrentExpressionAndReset() {
A current = getCurrentExpression();
reset();
return current;
}
/**
* Reset the thread bound expression
*/
public void reset() {
setCurrentExpression(null);
}
public <A> A createAlias(Class<A> clazz) {
return createProxy(clazz, new Class[0], new Object[0], null);
}
protected void setCurrentExpression(Expression<?> expression) {
this.current.set(expression);
}
@SuppressWarnings("unchecked")
protected <A> A createProxy(Class<A> clazz, Class<?>[] argumentTypes, Object[] arguments, Expression<?> path) {
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(AliasFactory.class.getClassLoader());
if (clazz.isInterface()) {
enhancer.setInterfaces(new Class[] {clazz, ManagedObject.class});
} else {
enhancer.setSuperclass(clazz);
enhancer.setInterfaces(new Class[] {ManagedObject.class});
}
enhancer.setCallback(new MethodAccessTracker(path));
return (A) enhancer.create(argumentTypes, arguments);
}
}
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.HashSet; import java.util.HashSet;
@@ -29,7 +30,7 @@ public class ExpeditionStartDataTest {
final String filename = "2018Apr28_05.csv.gz"; final String filename = "2018Apr28_05.csv.gz";
final ExpeditionStartData result = new ExpeditionCourseInferrer( final ExpeditionStartData result = new ExpeditionCourseInferrer(
RaceLogTrackingAdapterFactory.INSTANCE.getAdapter(DomainFactory.INSTANCE)).getStartData( RaceLogTrackingAdapterFactory.INSTANCE.getAdapter(DomainFactory.INSTANCE)).getStartData(
getClass().getResourceAsStream(filename), filename); getClass().getResourceAsStream(filename), filename, Charset.forName("UTF-8"));
assertNotNull(result); assertNotNull(result);
final Set<TimePoint> startTimes = new HashSet<>(); final Set<TimePoint> startTimes = new HashSet<>();
Util.addAll(result.getStartTimes(), startTimes); Util.addAll(result.getStartTimes(), startTimes);
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.trackfiles.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import com.sap.sailing.domain.trackimport.FormatNotSupportedException; import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
import com.sap.sailing.domain.trackimport.GPSFixImporter; import com.sap.sailing.domain.trackimport.GPSFixImporter;
@@ -17,8 +18,8 @@ public class AlwaysFailingGPSFixImporter implements GPSFixImporter {
} }
@Override @Override
public boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, public boolean importFixes(InputStream inputStream, Charset charset, Callback callback,
String sourceName) boolean inferSpeedAndBearing, String sourceName)
throws FormatNotSupportedException, IOException { throws FormatNotSupportedException, IOException {
int read = 0; int read = 0;
while (inputStream.read() != -1 && (failAfterAtMostSoManyBytes == -1 || read++ < failAfterAtMostSoManyBytes)) { while (inputStream.read() != -1 && (failAfterAtMostSoManyBytes == -1 || read++ < failAfterAtMostSoManyBytes)) {
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.trackfiles.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
@@ -108,6 +109,7 @@ import com.sap.sse.i18n.ResourceBundleStringMessages;
import com.sap.sse.security.SecurityService; import com.sap.sse.security.SecurityService;
import com.sap.sse.security.shared.HasPermissions.DefaultActions; import com.sap.sse.security.shared.HasPermissions.DefaultActions;
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions; import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
import com.sap.sse.util.FileItemHelper;
/** /**
* Importer for expedition data that imports all available data for a boat: * Importer for expedition data that imports all available data for a boat:
@@ -301,7 +303,8 @@ public class ExpeditionAllInOneImporter {
final List<Triple<String, String, String>> raceNameRaceColumnNameFleetnameList = new ArrayList<>(); final List<Triple<String, String, String>> raceNameRaceColumnNameFleetnameList = new ArrayList<>();
final List<DynamicTrackedRace> trackedRaces = new ArrayList<>(); final List<DynamicTrackedRace> trackedRaces = new ArrayList<>();
final ExpeditionCourseInferrer expeditionCourseInferrer = new ExpeditionCourseInferrer(adapter); final ExpeditionCourseInferrer expeditionCourseInferrer = new ExpeditionCourseInferrer(adapter);
final ExpeditionStartData startData = expeditionCourseInferrer.getStartData(fileItem.getInputStream(), filenameWithSuffix); final ExpeditionStartData startData = expeditionCourseInferrer.getStartData(fileItem.getInputStream(), filenameWithSuffix,
FileItemHelper.getCharset(fileItem, Charset.forName("UTF-8")));
final Iterable<String> additionalTrackedRaceNames = importStartData ? getNextRaceColumnNames(/* start race index */ 1, final Iterable<String> additionalTrackedRaceNames = importStartData ? getNextRaceColumnNames(/* start race index */ 1,
/* how many */ Util.size(startData.getStartTimes())) : Collections.emptySet(); /* how many */ Util.size(startData.getStartTimes())) : Collections.emptySet();
if (importMode == ImportMode.NEW_EVENT) { if (importMode == ImportMode.NEW_EVENT) {
@@ -435,8 +438,8 @@ public class ExpeditionAllInOneImporter {
try { try {
final WindImportResult windImportResult = new AbstractWindImporter.WindImportResult(); final WindImportResult windImportResult = new AbstractWindImporter.WindImportResult();
final WindSourceWithAdditionalID windSource = new WindSourceWithAdditionalID(WindSourceType.EXPEDITION, windSourceId); final WindSourceWithAdditionalID windSource = new WindSourceWithAdditionalID(WindSourceType.EXPEDITION, windSourceId);
final Map<InputStream, String> streamsWithFilenames = new HashMap<>(); final Map<InputStream, Pair<String, Charset>> streamsWithFilenames = new HashMap<>();
streamsWithFilenames.put(fileItem.getInputStream(), filenameWithSuffix); streamsWithFilenames.put(fileItem.getInputStream(), new Pair<>(filenameWithSuffix, FileItemHelper.getCharset(fileItem)));
new WindImporter().importWindToWindSourceAndTrackedRaces(service, windImportResult, windSource, trackedRaces, streamsWithFilenames); new WindImporter().importWindToWindSourceAndTrackedRaces(service, windImportResult, windSource, trackedRaces, streamsWithFilenames);
return new ImporterResult(eventId, regattaNameAndleaderboardName, leaderboardGroupName, return new ImporterResult(eventId, regattaNameAndleaderboardName, leaderboardGroupName,
regattaNameAndleaderboardName, raceNameRaceColumnNameFleetnameList, regattaNameAndleaderboardName, raceNameRaceColumnNameFleetnameList,
@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -69,17 +70,17 @@ public class ExpeditionCourseInferrer {
this.raceLogTrackingAdapter = raceLogTrackingAdapter; this.raceLogTrackingAdapter = raceLogTrackingAdapter;
} }
public ExpeditionStartData getStartData(InputStream inputStream, String filenameWithSuffix) public ExpeditionStartData getStartData(InputStream inputStream, String filenameWithSuffix, Charset charset)
throws IOException, FormatNotSupportedException { throws IOException, FormatNotSupportedException {
final List<TimePoint> startTimeCandidates = new ArrayList<>(); final List<TimePoint> startTimeCandidates = new ArrayList<>();
final List<GPSFix> startLinePortEndFixes = new ArrayList<>(); final List<GPSFix> startLinePortEndFixes = new ArrayList<>();
final List<GPSFix> startLineStarboardEndFixes = new ArrayList<>(); final List<GPSFix> startLineStarboardEndFixes = new ArrayList<>();
CompressedStreamsUtil.handlePotentiallyCompressedFiles(filenameWithSuffix, inputStream, new ExpeditionImportFileHandler() { CompressedStreamsUtil.handlePotentiallyCompressedFiles(filenameWithSuffix, inputStream, charset, new ExpeditionImportFileHandler() {
@Override @Override
protected void handleExpeditionFile(String fileName, InputStream inputStream) throws IOException, FormatNotSupportedException { protected void handleExpeditionFile(String fileName, InputStream inputStream, Charset charset) throws IOException, FormatNotSupportedException {
logger.fine("Start parsing Expedition file"); logger.fine("Start parsing Expedition file");
final AtomicLong lineNr = new AtomicLong(); final AtomicLong lineNr = new AtomicLong();
try (BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream))) { try (BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream, charset))) {
String headerLine = buffer.readLine(); String headerLine = buffer.readLine();
lineNr.incrementAndGet(); lineNr.incrementAndGet();
logger.fine("Validate and parse header columns"); logger.fine("Validate and parse header columns");
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.trackfiles.impl;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@@ -25,6 +26,7 @@ import com.sap.sailing.server.interfaces.RacingEventService;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException; import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TimeRange; import com.sap.sse.common.TimeRange;
import com.sap.sse.common.Util.Pair; import com.sap.sse.common.Util.Pair;
import com.sap.sse.util.FileItemHelper;
public class SensorDataImporter { public class SensorDataImporter {
private static final Logger logger = Logger.getLogger(SensorDataImporter.class.getName()); private static final Logger logger = Logger.getLogger(SensorDataImporter.class.getName());
@@ -73,7 +75,8 @@ public class SensorDataImporter {
try (BufferedInputStream in = new BufferedInputStream(fi.getInputStream())) { try (BufferedInputStream in = new BufferedInputStream(fi.getInputStream())) {
final String filename = fi.getName(); final String filename = fi.getName();
try { try {
importerToUse.importFixes(in, new DoubleVectorFixImporter.Callback() { final Charset charset = FileItemHelper.getCharset(fi);
importerToUse.importFixes(in, charset, new DoubleVectorFixImporter.Callback() {
@Override @Override
public void addFixes(Iterable<DoubleVectorFix> fixes, TrackFileImportDeviceIdentifier device) { public void addFixes(Iterable<DoubleVectorFix> fixes, TrackFileImportDeviceIdentifier device) {
storeFixes(fixes, device); storeFixes(fixes, device);
@@ -31,6 +31,7 @@ import com.sap.sse.common.TimeRange;
import com.sap.sse.common.TransformationException; import com.sap.sse.common.TransformationException;
import com.sap.sse.common.TypeBasedServiceFinderFactory; import com.sap.sse.common.TypeBasedServiceFinderFactory;
import com.sap.sse.common.Util.Pair; import com.sap.sse.common.Util.Pair;
import com.sap.sse.util.FileItemHelper;
public class TrackFilesImporter { public class TrackFilesImporter {
private static final Logger logger = Logger.getLogger(TrackFilesImporter.class.getName()); private static final Logger logger = Logger.getLogger(TrackFilesImporter.class.getName());
@@ -78,7 +79,7 @@ public class TrackFilesImporter {
logger.log(Level.INFO, "Trying to import file " + fileName + " with importer " + importer.getType()); logger.log(Level.INFO, "Trying to import file " + fileName + " with importer " + importer.getType());
try (BufferedInputStream in = new BufferedInputStream(fileItem.getInputStream())) { try (BufferedInputStream in = new BufferedInputStream(fileItem.getInputStream())) {
try { try {
boolean ok = importer.importFixes(in, new Callback() { boolean ok = importer.importFixes(in, FileItemHelper.getCharset(fileItem), new Callback() {
@Override @Override
public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) { public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) {
storeFix(fix, device); storeFix(fix, device);
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.windimport;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@@ -24,7 +25,9 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter.WindImportResult.RaceEntry; import com.sap.sailing.server.gateway.windimport.AbstractWindImporter.WindImportResult.RaceEntry;
import com.sap.sailing.server.interfaces.RacingEventService; import com.sap.sailing.server.interfaces.RacingEventService;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.security.shared.HasPermissions.DefaultActions; import com.sap.sse.security.shared.HasPermissions.DefaultActions;
import com.sap.sse.util.FileItemHelper;
public abstract class AbstractWindImporter { public abstract class AbstractWindImporter {
public static class UploadRequest { public static class UploadRequest {
@@ -158,11 +161,11 @@ public abstract class AbstractWindImporter {
} }
} }
} }
final Map<InputStream, String> streamsWithFilenames = new HashMap<>(); final Map<InputStream, Pair<String, Charset>> streamsWithFilenamesAndCharsets = new HashMap<>();
for (FileItem file : uploadRequest.files) { for (FileItem file : uploadRequest.files) {
streamsWithFilenames.put(file.getInputStream(), file.getName()); streamsWithFilenamesAndCharsets.put(file.getInputStream(), new Pair<>(file.getName(), FileItemHelper.getCharset(file, Charset.forName("UTF-8"))));
} }
importWindToWindSourceAndTrackedRaces(service, windImportResult, windSource, trackedRaces, streamsWithFilenames); importWindToWindSourceAndTrackedRaces(service, windImportResult, windSource, trackedRaces, streamsWithFilenamesAndCharsets);
} }
/** /**
@@ -171,9 +174,9 @@ public abstract class AbstractWindImporter {
* fixes for which no explicit wind source has been returned by the {@link #importWind(WindSource, Map)} method. * fixes for which no explicit wind source has been returned by the {@link #importWind(WindSource, Map)} method.
*/ */
public void importWindToWindSourceAndTrackedRaces(RacingEventService service, WindImportResult windImportResult, WindSource defaultWindSource, public void importWindToWindSourceAndTrackedRaces(RacingEventService service, WindImportResult windImportResult, WindSource defaultWindSource,
List<DynamicTrackedRace> trackedRaces, final Map<InputStream, String> streamsWithFilenames) List<DynamicTrackedRace> trackedRaces, final Map<InputStream, Pair<String, Charset>> streamsWithFilenamesAndCharsets)
throws IOException, InterruptedException, FormatNotSupportedException { throws IOException, InterruptedException, FormatNotSupportedException {
Map<WindSource, Iterable<Wind>> windFixes = importWind(defaultWindSource, streamsWithFilenames); Map<WindSource, Iterable<Wind>> windFixes = importWind(defaultWindSource, streamsWithFilenamesAndCharsets);
for (final Entry<WindSource, Iterable<Wind>> windForSource : windFixes.entrySet()) { for (final Entry<WindSource, Iterable<Wind>> windForSource : windFixes.entrySet()) {
if (!Util.isEmpty(windForSource.getValue())) { if (!Util.isEmpty(windForSource.getValue())) {
for (DynamicTrackedRace trackedRace : trackedRaces) { for (DynamicTrackedRace trackedRace : trackedRaces) {
@@ -197,9 +200,14 @@ public abstract class AbstractWindImporter {
* the default wind source to use as the key of the map returned; implementations may, however, use this * the default wind source to use as the key of the map returned; implementations may, however, use this
* default wind source only as a copy template to produce finer-grained wind sources based on what the * default wind source only as a copy template to produce finer-grained wind sources based on what the
* import stream contains * import stream contains
* @param streamsWithFilenamesAndCharsets
* keys are the {@link InputStream}s from which to read wind data; values are pairs of which the first
* element is the filename, and the second is the character set to use for decoding the stream.
* The character sets must not be {@code null}. See {@link Charset#defaultCharset()}.
* @return a map whose values are the wind fixes imported, keyed by the {@link WindSource} to which to add them. * @return a map whose values are the wind fixes imported, keyed by the {@link WindSource} to which to add them.
*/ */
protected abstract Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource, Map<InputStream, String> streamsWithFilenames) protected abstract Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource,
Map<InputStream, Pair<String, Charset>> streamsWithFilenamesAndCharsets)
throws IOException, InterruptedException, FormatNotSupportedException; throws IOException, InterruptedException, FormatNotSupportedException;
protected abstract WindSource getDefaultWindSource(UploadRequest uploadRequest); protected abstract WindSource getDefaultWindSource(UploadRequest uploadRequest);
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.windimport.bravo;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -27,6 +28,7 @@ import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter; import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
import com.sap.sailing.server.trackfiles.impl.BaseBravoDataImporterImpl; import com.sap.sailing.server.trackfiles.impl.BaseBravoDataImporterImpl;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.DegreeBearingImpl; import com.sap.sse.common.impl.DegreeBearingImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
@@ -50,16 +52,19 @@ public class BravoWindImporter extends AbstractWindImporter {
} }
@Override @Override
protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource, Map<InputStream, String> inputStreamsAndFilenames) throws IOException, InterruptedException, FormatNotSupportedException { protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource,
Map<InputStream, Pair<String, Charset>> inputStreamsAndFilenamesAndCharsets)
throws IOException, InterruptedException, FormatNotSupportedException {
final Iterable<Wind> windFixes; final Iterable<Wind> windFixes;
if (inputStreamsAndFilenames != null && inputStreamsAndFilenames.size() == 1) { if (inputStreamsAndFilenamesAndCharsets != null && inputStreamsAndFilenamesAndCharsets.size() == 1) {
logger.info("Reading Bravo wind data from "+inputStreamsAndFilenames.values().iterator().next()); final Pair<String, Charset> filenameAndCharset = inputStreamsAndFilenamesAndCharsets.values().iterator().next();
windFixes = readWind(inputStreamsAndFilenames.values().iterator().next(), inputStreamsAndFilenames.keySet().iterator().next()); logger.info("Reading Bravo wind data from "+filenameAndCharset);
windFixes = readWind(filenameAndCharset.getA(), inputStreamsAndFilenamesAndCharsets.keySet().iterator().next(), filenameAndCharset.getB());
} else { } else {
final List<Wind> windList = new LinkedList<>(); final List<Wind> windList = new LinkedList<>();
for (final Entry<InputStream, String> inputStreamAndFileName : inputStreamsAndFilenames.entrySet()) { for (final Entry<InputStream, Pair<String, Charset>> inputStreamAndFileName : inputStreamsAndFilenamesAndCharsets.entrySet()) {
logger.info("Reading Bravo wind data from "+inputStreamAndFileName.getValue()); logger.info("Reading Bravo wind data from "+inputStreamAndFileName.getValue().getA());
Util.addAll(readWind(inputStreamAndFileName.getValue(), inputStreamAndFileName.getKey()), windList); Util.addAll(readWind(inputStreamAndFileName.getValue().getA(), inputStreamAndFileName.getKey(), inputStreamAndFileName.getValue().getB()), windList);
} }
windFixes = windList; windFixes = windList;
} }
@@ -72,7 +77,8 @@ public class BravoWindImporter extends AbstractWindImporter {
Lat, Lon, TWS, TWD; Lat, Lon, TWS, TWD;
} }
private Iterable<Wind> readWind(String filename, InputStream inputStream) throws InterruptedException, IOException, FormatNotSupportedException { private Iterable<Wind> readWind(String filename, InputStream inputStream, Charset charset)
throws InterruptedException, IOException, FormatNotSupportedException {
final List<Wind> result = new LinkedList<>(); final List<Wind> result = new LinkedList<>();
Map<String, Integer> columnsMap = new HashMap<>(); Map<String, Integer> columnsMap = new HashMap<>();
for (final Fields field : Fields.values()) { for (final Fields field : Fields.values()) {
@@ -101,7 +107,7 @@ public class BravoWindImporter extends AbstractWindImporter {
while ((entry=zipInputStream.getNextEntry()) != null) { while ((entry=zipInputStream.getNextEntry()) != null) {
if (entry.getName().toLowerCase().endsWith(".txt")) { if (entry.getName().toLowerCase().endsWith(".txt")) {
logger.info("Reading Bravo wind data from "+filename+"'s ZIP entry "+entry.getName()); logger.info("Reading Bravo wind data from "+filename+"'s ZIP entry "+entry.getName());
importer.importFixes(zipInputStream, callback, entry.getName(), BRAVO_WIND_IMPORT, /* downsample */ false); importer.importFixes(zipInputStream, Charset.forName("UTF-8"), callback, entry.getName(), BRAVO_WIND_IMPORT, /* downsample */ false);
} }
} }
} }
@@ -113,7 +119,7 @@ public class BravoWindImporter extends AbstractWindImporter {
} else { } else {
actualFileName = filename; actualFileName = filename;
} }
importer.importFixes(inputStream, callback, actualFileName, BRAVO_WIND_IMPORT, /* downsample */ false); importer.importFixes(inputStream, Charset.forName("UTF-8"), callback, actualFileName, BRAVO_WIND_IMPORT, /* downsample */ false);
} }
return result; return result;
} }
@@ -2,10 +2,12 @@ package com.sap.sailing.server.gateway.windimport.expedition;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import com.sap.sailing.domain.common.Wind; import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSource;
@@ -17,6 +19,7 @@ import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
import com.sap.sailing.server.trackfiles.impl.CompressedStreamsUtil; import com.sap.sailing.server.trackfiles.impl.CompressedStreamsUtil;
import com.sap.sailing.server.trackfiles.impl.ExpeditionImportFileHandler; import com.sap.sailing.server.trackfiles.impl.ExpeditionImportFileHandler;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
public class WindImporter extends AbstractWindImporter { public class WindImporter extends AbstractWindImporter {
@@ -32,12 +35,14 @@ public class WindImporter extends AbstractWindImporter {
} }
@Override @Override
protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource, Map<InputStream, String> streamsWithFilenames) throws IOException, FormatNotSupportedException { protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource,
Map<InputStream, Pair<String, Charset>> streamsWithFilenames)
throws IOException, FormatNotSupportedException {
final List<Wind> windFixes = new ArrayList<>(); final List<Wind> windFixes = new ArrayList<>();
for (final Map.Entry<InputStream, String> entry : streamsWithFilenames.entrySet()) { for (final Entry<InputStream, Pair<String, Charset>> entry : streamsWithFilenames.entrySet()) {
CompressedStreamsUtil.handlePotentiallyCompressedFiles(entry.getValue(), entry.getKey(), new ExpeditionImportFileHandler() { CompressedStreamsUtil.handlePotentiallyCompressedFiles(entry.getValue().getA(), entry.getKey(), entry.getValue().getB(), new ExpeditionImportFileHandler() {
@Override @Override
protected void handleExpeditionFile(String fileName, InputStream inputStream) throws IOException { protected void handleExpeditionFile(String fileName, InputStream inputStream, Charset charset) throws IOException {
Util.addAll(WindLogParser.importWind(inputStream), windFixes); Util.addAll(WindLogParser.importWind(inputStream), windFixes);
} }
}); });
@@ -2,8 +2,10 @@ package com.sap.sailing.server.gateway.windimport.grib;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -18,6 +20,7 @@ import com.sap.sailing.grib.GribWindField;
import com.sap.sailing.grib.GribWindFieldFactory; import com.sap.sailing.grib.GribWindFieldFactory;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter; import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
public class GribWindImporter extends AbstractWindImporter { public class GribWindImporter extends AbstractWindImporter {
private static final Logger logger = Logger.getLogger(GribWindImporter.class.getName()); private static final Logger logger = Logger.getLogger(GribWindImporter.class.getName());
@@ -34,7 +37,12 @@ public class GribWindImporter extends AbstractWindImporter {
} }
@Override @Override
protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource, Map<InputStream, String> inputStreamsAndFilenames) throws IOException { protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource, Map<InputStream, Pair<String, Charset>> inputStreamsAndFilenamesAndCharsets) throws IOException {
// GRIB files are, as the acronym expansion "Gridded BINARY" suggests, binary files where charset / encoding is not relevant:
final Map<InputStream, String> inputStreamsAndFilenames = new HashMap<>();
for (final Entry<InputStream, Pair<String, Charset>> e : inputStreamsAndFilenamesAndCharsets.entrySet()) {
inputStreamsAndFilenames.put(e.getKey(), e.getValue().getA());
}
final GribWindField windField = GribWindFieldFactory.INSTANCE.createGribWindFieldFromStreams(logger, Level.INFO, inputStreamsAndFilenames); final GribWindField windField = GribWindFieldFactory.INSTANCE.createGribWindFieldFromStreams(logger, Level.INFO, inputStreamsAndFilenames);
final Map<WindSource, Iterable<Wind>> result = new HashMap<>(); final Map<WindSource, Iterable<Wind>> result = new HashMap<>();
final Map<Position, WindSource> windSourcesByPosition = new HashMap<>(); final Map<Position, WindSource> windSourcesByPosition = new HashMap<>();
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.windimport.nmea;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -18,6 +19,7 @@ import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.nmeaconnector.NmeaFactory; import com.sap.sailing.nmeaconnector.NmeaFactory;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter; import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
public class NmeaWindImporter extends AbstractWindImporter { public class NmeaWindImporter extends AbstractWindImporter {
@@ -38,16 +40,19 @@ public class NmeaWindImporter extends AbstractWindImporter {
} }
@Override @Override
protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource, Map<InputStream, String> inputStreamsAndFilenames) throws IOException, InterruptedException { protected Map<WindSource, Iterable<Wind>> importWind(WindSource defaultWindSource,
Map<InputStream, Pair<String, Charset>> inputStreamsAndFilenamesAndCharsets) throws IOException, InterruptedException {
final Iterable<Wind> windFixes; final Iterable<Wind> windFixes;
if (inputStreamsAndFilenames != null && inputStreamsAndFilenames.size() == 1) { if (inputStreamsAndFilenamesAndCharsets != null && inputStreamsAndFilenamesAndCharsets.size() == 1) {
logger.info("Reading NMEA wind data from "+inputStreamsAndFilenames.values().iterator().next()); final Pair<String, Charset> filenameAndCharset = inputStreamsAndFilenamesAndCharsets.values().iterator().next();
windFixes = readWind(inputStreamsAndFilenames.values().iterator().next(), inputStreamsAndFilenames.keySet().iterator().next()); logger.info("Reading NMEA wind data from "+filenameAndCharset);
windFixes = readWind(filenameAndCharset.getA(), inputStreamsAndFilenamesAndCharsets.keySet().iterator().next(), filenameAndCharset.getB());
} else { } else {
final List<Wind> windList = new LinkedList<>(); final List<Wind> windList = new LinkedList<>();
for (final Entry<InputStream, String> inputStreamAndFileName : inputStreamsAndFilenames.entrySet()) { for (final Entry<InputStream, Pair<String, Charset>> inputStreamAndFileName : inputStreamsAndFilenamesAndCharsets.entrySet()) {
logger.info("Reading NMEA wind data from "+inputStreamAndFileName.getValue()); logger.info("Reading NMEA wind data from "+inputStreamAndFileName.getValue());
Util.addAll(readWind(inputStreamAndFileName.getValue(), inputStreamAndFileName.getKey()), windList); Util.addAll(readWind(inputStreamAndFileName.getValue().getA(), inputStreamAndFileName.getKey(),
inputStreamAndFileName.getValue().getB()), windList);
} }
windFixes = windList; windFixes = windList;
} }
@@ -56,7 +61,7 @@ public class NmeaWindImporter extends AbstractWindImporter {
return result; return result;
} }
private Iterable<Wind> readWind(String filename, InputStream inputStream) throws InterruptedException, IOException { private Iterable<Wind> readWind(String filename, InputStream inputStream, Charset charset) throws InterruptedException, IOException {
final Iterable<Wind> result; final Iterable<Wind> result;
if (filename.toLowerCase().endsWith("zip")) { if (filename.toLowerCase().endsWith("zip")) {
logger.info("NMEA file "+filename+" is a ZIP file"); logger.info("NMEA file "+filename+" is a ZIP file");
@@ -2,6 +2,7 @@ package com.sap.sailing.server.trackfiles.test;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Map; import java.util.Map;
import org.junit.Assert; import org.junit.Assert;
@@ -49,7 +50,7 @@ public abstract class AbstractBravoDataImportTest {
protected void testImport(ImportDataDefinition importData) throws FormatNotSupportedException, IOException { protected void testImport(ImportDataDefinition importData) throws FormatNotSupportedException, IOException {
try (final InputStream is = importData.getInputStream()) { try (final InputStream is = importData.getInputStream()) {
bravoDataImporter.importFixes(is, (fixes, device) -> { bravoDataImporter.importFixes(is, Charset.defaultCharset(), (fixes, device) -> {
callbackCallCount+=Util.size(fixes); callbackCallCount+=Util.size(fixes);
}, "filename", "source", /* downsample */ true); }, "filename", "source", /* downsample */ true);
Assert.assertEquals(importData.getExpectedFixesCount(), downsampler.getCountSourceTtl()); Assert.assertEquals(importData.getExpectedFixesCount(), downsampler.getCountSourceTtl());
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@@ -57,11 +58,11 @@ public class BravoExtendedDataImportTest extends AbstractBravoDataImportTest {
try (final ByteArrayInputStream inputStream = new ByteArrayInputStream(( try (final ByteArrayInputStream inputStream = new ByteArrayInputStream((
HEADER_ORDER_DEFAULT+DUMMY_CONTENT+DUMMY_CONTENT2).getBytes(StandardCharsets.UTF_8))) { HEADER_ORDER_DEFAULT+DUMMY_CONTENT+DUMMY_CONTENT2).getBytes(StandardCharsets.UTF_8))) {
bravoDataImporter.importFixes(inputStream, bravoDataImporter.importFixes(inputStream,
(fixes, device) -> { Charset.defaultCharset(), (fixes, device) -> {
for (DoubleVectorFix fix : fixes) { for (DoubleVectorFix fix : fixes) {
track.add(new BravoExtendedFixImpl(fix)); track.add(new BravoExtendedFixImpl(fix));
} }
}, "filename", "source", /* downsample */ true); }, "filename", "source", /* downsample */ true);
final TimePoint t1 = new MillisecondsTimePoint(1500648308500l); final TimePoint t1 = new MillisecondsTimePoint(1500648308500l);
final TimePoint t2 = new MillisecondsTimePoint(1500648309500l); final TimePoint t2 = new MillisecondsTimePoint(1500648309500l);
final BravoExtendedFix bef1, bef2; final BravoExtendedFix bef1, bef2;
@@ -4,6 +4,7 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@@ -33,7 +34,7 @@ public class ExpeditionDataImportTest {
protected void testImport(ImportDataDefinition importData) throws FormatNotSupportedException, IOException { protected void testImport(ImportDataDefinition importData) throws FormatNotSupportedException, IOException {
try (final InputStream is = importData.getInputStream()) { try (final InputStream is = importData.getInputStream()) {
expeditionDataImporter.importFixes(is, (fixes, device) -> { expeditionDataImporter.importFixes(is, Charset.defaultCharset(), (fixes, device) -> {
for (DoubleVectorFix fix : fixes) { for (DoubleVectorFix fix : fixes) {
if (fix != null) { if (fix != null) {
callbackCallCount++; callbackCallCount++;
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
@@ -214,7 +215,7 @@ public class JumpyTrackSmootheningTest {
inputStream = fileInputStream; inputStream = fileInputStream;
} }
RouteConverterGPSFixImporterFactory.INSTANCE.createRouteConverterGPSFixImporter().importFixes(inputStream, RouteConverterGPSFixImporterFactory.INSTANCE.createRouteConverterGPSFixImporter().importFixes(inputStream,
(fix, device)->track.add((GPSFixMoving) fix), /* inferSpeedAndBearing */ false, filename); Charset.defaultCharset(), (fix, device)->track.add((GPSFixMoving) fix), /* inferSpeedAndBearing */ false, filename);
return track; return track;
} }
@@ -6,6 +6,7 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List; import java.util.List;
import org.junit.Test; import org.junit.Test;
@@ -44,7 +45,7 @@ public class RouteConverterGpx11ExtensionsTest {
return (GPSFix) invocation.callRealMethod(); return (GPSFix) invocation.callRealMethod();
} }
}).when(importer).convertToGPSFix(any(BaseNavigationPosition.class)); }).when(importer).convertToGPSFix(any(BaseNavigationPosition.class));
importer.importFixes(in, new com.sap.sailing.domain.trackimport.GPSFixImporter.Callback() { importer.importFixes(in, Charset.defaultCharset(), new com.sap.sailing.domain.trackimport.GPSFixImporter.Callback() {
@Override @Override
public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) { public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) {
} }
@@ -4,6 +4,7 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -26,7 +27,7 @@ public class TrackFileImportTest {
@Test @Test
public void testGpx() throws IOException, FormatNotSupportedException { public void testGpx() throws IOException, FormatNotSupportedException {
try (InputStream in = getClass().getResourceAsStream("/Cardiff Race17 - COMPETITORS.gpx")) { try (InputStream in = getClass().getResourceAsStream("/Cardiff Race17 - COMPETITORS.gpx")) {
new RouteConverterGPSFixImporterImpl().importFixes(in, new Callback() { new RouteConverterGPSFixImporterImpl().importFixes(in, Charset.defaultCharset(), new Callback() {
@Override @Override
public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) { public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) {
if (fix instanceof GPSFixMoving) { if (fix instanceof GPSFixMoving) {
@@ -41,7 +42,7 @@ public class TrackFileImportTest {
@Test @Test
public void testKmlOnlyLatLong() throws IOException, FormatNotSupportedException { public void testKmlOnlyLatLong() throws IOException, FormatNotSupportedException {
try (InputStream in = getClass().getResourceAsStream("/Cardiff Race22 - COMPETITORS.kml")) { try (InputStream in = getClass().getResourceAsStream("/Cardiff Race22 - COMPETITORS.kml")) {
new RouteConverterGPSFixImporterImpl().importFixes(in, new Callback() { new RouteConverterGPSFixImporterImpl().importFixes(in, Charset.defaultCharset(), new Callback() {
@Override @Override
public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) { public void addFix(GPSFix fix, TrackFileImportDeviceIdentifier device) {
if (fix instanceof GPSFix) { if (fix instanceof GPSFix) {
@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -66,8 +67,8 @@ public class BaseBravoDataImporterImpl extends AbstractDoubleVectorFixImporter {
* if {@code true}, fixes will be down-sampled to a 1Hz frequency before being emitted to the * if {@code true}, fixes will be down-sampled to a 1Hz frequency before being emitted to the
* {@code callback}. Otherwise, all fixes read will be forwarded straight to the {@link Callback}. * {@code callback}. Otherwise, all fixes read will be forwarded straight to the {@link Callback}.
*/ */
public boolean importFixes(InputStream inputStream, Callback callback, final String filename, String sourceName, public boolean importFixes(InputStream inputStream, Charset charset, Callback callback, final String filename,
boolean downsample) throws FormatNotSupportedException, IOException { String sourceName, boolean downsample) throws FormatNotSupportedException, IOException {
final TrackFileImportDeviceIdentifier trackIdentifier = new TrackFileImportDeviceIdentifierImpl( final TrackFileImportDeviceIdentifier trackIdentifier = new TrackFileImportDeviceIdentifierImpl(
UUID.randomUUID(), filename, sourceName, MillisecondsTimePoint.now()); UUID.randomUUID(), filename, sourceName, MillisecondsTimePoint.now());
LOG.fine("Import CSV from " + filename); LOG.fine("Import CSV from " + filename);
@@ -2,6 +2,7 @@ package com.sap.sailing.server.trackfiles.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -53,8 +54,8 @@ public abstract class BaseRouteConverterGPSFixImporterImpl extends BaseGPSFixImp
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@Override @Override
public boolean importFixes(InputStream inputStream, Callback callback, boolean inferSpeedAndBearing, public boolean importFixes(InputStream inputStream, Charset charset, Callback callback,
String sourceName) boolean inferSpeedAndBearing, String sourceName)
throws IOException, FormatNotSupportedException { throws IOException, FormatNotSupportedException {
NavigationFormatParser parser = new NavigationFormatParser(); NavigationFormatParser parser = new NavigationFormatParser();
List<BaseRoute> routes; List<BaseRoute> routes;
@@ -2,6 +2,7 @@ package com.sap.sailing.server.trackfiles.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
@@ -15,28 +16,28 @@ public final class CompressedStreamsUtil {
private static final String GZIP_SUFFIX = ".gz"; private static final String GZIP_SUFFIX = ".gz";
public interface FileHandler { public interface FileHandler {
void handle(String fileName, InputStream inputStream) throws IOException, FormatNotSupportedException; void handle(String fileName, InputStream inputStream, Charset charset) throws IOException, FormatNotSupportedException;
} }
private CompressedStreamsUtil() { private CompressedStreamsUtil() {
} }
public static void handlePotentiallyCompressedFiles(final String filename, final InputStream inputStream, public static void handlePotentiallyCompressedFiles(final String filename, final InputStream inputStream,
FileHandler fileHandler) throws IOException, FormatNotSupportedException { Charset charset, FileHandler fileHandler) throws IOException, FormatNotSupportedException {
try (InputStream stream = inputStream) { try (InputStream stream = inputStream) {
if (filename.toLowerCase().endsWith(".zip")) { if (filename.toLowerCase().endsWith(".zip")) {
logger.info("Bravo file " + filename + " is a ZIP file"); logger.info("Bravo file " + filename + " is a ZIP file");
final ZipInputStream zipInputStream = new ZipInputStream(inputStream); final ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry entry; ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) { while ((entry = zipInputStream.getNextEntry()) != null) {
fileHandler.handle(entry.getName(), zipInputStream); fileHandler.handle(entry.getName(), zipInputStream, charset);
} }
} else if (filename.toLowerCase().endsWith(GZIP_SUFFIX)) { } else if (filename.toLowerCase().endsWith(GZIP_SUFFIX)) {
final GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream); final GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
final String actualFileName = filename.substring(0, filename.length() - GZIP_SUFFIX.length()); final String actualFileName = filename.substring(0, filename.length() - GZIP_SUFFIX.length());
fileHandler.handle(actualFileName, gzipInputStream); fileHandler.handle(actualFileName, gzipInputStream, charset);
} else { } else {
fileHandler.handle(filename, inputStream); fileHandler.handle(filename, inputStream, charset);
} }
} }
} }
@@ -6,6 +6,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@@ -43,7 +44,7 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
/** /**
* Importer for CSV data files from Expedition log files, as used, e.g., by Team Phoenix. Note that this importer so far * Importer for CSV data files from Expedition log files, as used, e.g., by Team Phoenix. Note that this importer so far
* ignores the {@code downsample} parameter of the * ignores the {@code downsample} parameter of the
* {@link #importFixes(InputStream, com.sap.sailing.domain.trackimport.BaseDoubleVectorFixImporter.Callback, String, String, boolean)} * {@link #importFixes(InputStream, Charset, com.sap.sailing.domain.trackimport.BaseDoubleVectorFixImporter.Callback, String, String, boolean)}
* method. * method.
*/ */
public class ExpeditionExtendedDataImporterImpl extends AbstractDoubleVectorFixImporter public class ExpeditionExtendedDataImporterImpl extends AbstractDoubleVectorFixImporter
@@ -94,14 +95,14 @@ public class ExpeditionExtendedDataImporterImpl extends AbstractDoubleVectorFixI
} }
@Override @Override
public boolean importFixes(InputStream inputStream, final Callback callback, String filename, String sourceName, public boolean importFixes(InputStream inputStream, Charset charset, final Callback callback, String filename,
boolean downsample) throws FormatNotSupportedException, IOException { String sourceName, boolean downsample) throws FormatNotSupportedException, IOException {
final TrackFileImportDeviceIdentifier trackIdentifier = new TrackFileImportDeviceIdentifierImpl( final TrackFileImportDeviceIdentifier trackIdentifier = new TrackFileImportDeviceIdentifierImpl(
UUID.randomUUID(), filename, sourceName, MillisecondsTimePoint.now()); UUID.randomUUID(), filename, sourceName, MillisecondsTimePoint.now());
final AtomicBoolean importedFixes = new AtomicBoolean(false); final AtomicBoolean importedFixes = new AtomicBoolean(false);
CompressedStreamsUtil.handlePotentiallyCompressedFiles(filename, inputStream, new ExpeditionImportFileHandler() { CompressedStreamsUtil.handlePotentiallyCompressedFiles(filename, inputStream, charset, new ExpeditionImportFileHandler() {
@Override @Override
protected void handleExpeditionFile(String fileName, InputStream inputStream) throws IOException, FormatNotSupportedException { protected void handleExpeditionFile(String fileName, InputStream inputStream, Charset charset) throws IOException, FormatNotSupportedException {
logger.fine("Start parsing Expedition file"); logger.fine("Start parsing Expedition file");
final AtomicLong lineNr = new AtomicLong(); final AtomicLong lineNr = new AtomicLong();
try (BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream))) { try (BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream))) {
@@ -2,6 +2,7 @@ package com.sap.sailing.server.trackfiles.impl;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@@ -22,7 +23,7 @@ public abstract class ExpeditionImportFileHandler implements CompressedStreamsUt
} }
@Override @Override
public final void handle(String fileName, InputStream inputStream) throws IOException, FormatNotSupportedException { public final void handle(String fileName, InputStream inputStream, Charset charset) throws IOException, FormatNotSupportedException {
final String lowerCaseFileName = fileName.toLowerCase(); final String lowerCaseFileName = fileName.toLowerCase();
boolean extensionSupported = false; boolean extensionSupported = false;
for (String extension : supportedExpeditionLogFileExtensions) { for (String extension : supportedExpeditionLogFileExtensions) {
@@ -32,9 +33,9 @@ public abstract class ExpeditionImportFileHandler implements CompressedStreamsUt
} }
} }
if (extensionSupported) { if (extensionSupported) {
handleExpeditionFile(lowerCaseFileName, inputStream); handleExpeditionFile(lowerCaseFileName, inputStream, charset);
} }
} }
protected abstract void handleExpeditionFile(String fileName, InputStream inputStream) throws IOException, FormatNotSupportedException; protected abstract void handleExpeditionFile(String fileName, InputStream inputStream, Charset charset) throws IOException, FormatNotSupportedException;
} }
@@ -13,6 +13,7 @@
<intAttribute key="default_start_level" value="4"/> <intAttribute key="default_start_level" value="4"/>
<setAttribute key="deselected_workspace_bundles"/> <setAttribute key="deselected_workspace_bundles"/>
<booleanAttribute key="includeOptional" value="false"/> <booleanAttribute key="includeOptional" value="false"/>
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.pde.ui.launcher.PDESourceLookupDirector"/> <stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.pde.ui.launcher.PDESourceLookupDirector"/>
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10; &lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10; &lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;directory nest=&amp;quot;false&amp;quot; path=&amp;quot;C:\Users\georg\Documents\Business\Kunden\OIO\SAPsailing\jetty.project\apache-jsp\src\main\java&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.directory&quot;/&gt;&#13;&#10; &lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;classpathContainer path=&amp;quot;com.google.gwt.eclipse.core.GWT_CONTAINER&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.classpathContainer&quot;/&gt;&#13;&#10; &lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10; &lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/> <stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10; &lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10; &lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;directory nest=&amp;quot;false&amp;quot; path=&amp;quot;C:\Users\georg\Documents\Business\Kunden\OIO\SAPsailing\jetty.project\apache-jsp\src\main\java&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.directory&quot;/&gt;&#13;&#10; &lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;classpathContainer path=&amp;quot;com.google.gwt.eclipse.core.GWT_CONTAINER&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.classpathContainer&quot;/&gt;&#13;&#10; &lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10; &lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
@@ -33,289 +34,285 @@
<stringAttribute key="profilingTraceType-PERFORMANCE_HOTSPOT_TRACE" value="KEY_IGNORE_SLEEPING_THREADS%CTX_KEY%false%CTX_ENTRY%KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%true%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/> <stringAttribute key="profilingTraceType-PERFORMANCE_HOTSPOT_TRACE" value="KEY_IGNORE_SLEEPING_THREADS%CTX_KEY%false%CTX_ENTRY%KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%true%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/>
<stringAttribute key="profilingTraceType-SYNCHRONIZATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/> <stringAttribute key="profilingTraceType-SYNCHRONIZATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/>
<setAttribute key="selected_target_bundles"> <setAttribute key="selected_target_bundles">
<setEntry value="routeconverter@default:default"/> <setEntry value="com.amazon.aws.aws-java-api.source"/>
<setEntry value="org.apache.commons.codec@default:default"/> <setEntry value="com.amazon.aws.aws-java-api@default:default"/>
<setEntry value="org.apache.poi@default:default"/> <setEntry value="com.chargebee.chargebee-java@default:default"/>
<setEntry value="org.apache.poi.ooxml@default:default"/> <setEntry value="com.github.haifengl.smile-core.source"/>
<setEntry value="org.apache.poi.ooxml.schemas@default:default"/> <setEntry value="com.github.haifengl.smile-core@default:default"/>
<setEntry value="org.apache.commons.collections4@default:default"/> <setEntry value="com.github.haifengl.smile-data.source"/>
<setEntry value="org.apache.commons.compress@default:default"/> <setEntry value="com.github.haifengl.smile-data@default:default"/>
<setEntry value="org.apache.poi.source@default:default"/> <setEntry value="com.github.haifengl.smile-graph.source"/>
<setEntry value="org.apache.poi.ooxml.source@default:default"/> <setEntry value="com.github.haifengl.smile-graph@default:default"/>
<setEntry value="org.apache.commons.collections4.source@default:default"/> <setEntry value="com.github.haifengl.smile-math.source"/>
<setEntry value="org.apache.commons.compress.source@default:default"/> <setEntry value="com.github.haifengl.smile-math@default:default"/>
<setEntry value="org.dom4j@default:default"/> <setEntry value="com.google.gson.source"/>
<setEntry value="org.apache.xmlbeans@default:default"/> <setEntry value="com.google.gson@default:default"/>
<setEntry value="org.apache.commons.math@default:default"/> <setEntry value="com.jcraft.jsch@default:default"/>
<setEntry value="org.apache.httpcomponents.httpclient@default:default"/> <setEntry value="com.rabbitmq.client.source"/>
<setEntry value="org.apache.httpcomponents.httpcore@default:default"/> <setEntry value="com.rabbitmq.client@default:default"/>
<setEntry value="org.hyperic.sigar@default:default"/> <setEntry value="com.sap.db.jdbc.source"/>
<setEntry value="com.sun.jersey.contribs.jersey-multipart@default:default"/> <setEntry value="com.sap.db.jdbc@default:default"/>
<setEntry value="javax.validation@default:default"/> <setEntry value="com.sun.activation.javax.activation@default:default"/>
<setEntry value="org.apache.commons.fileupload@default:default"/> <setEntry value="com.sun.istack.commons-runtime@default:default"/>
<setEntry value="org.jvnet.mimepull@default:default"/> <setEntry value="com.sun.jersey.contribs.jersey-multipart@default:default"/>
<setEntry value="org.apache.commons.math3@default:default"/> <setEntry value="com.sun.jersey@default:default"/>
<setEntry value="org.mongodb.driver-core@default:default"/> <setEntry value="com.sun.mail.javax.mail@default:default"/>
<setEntry value="org.mongodb.driver-core.source@default:default"/> <setEntry value="com.sun.xml.bind.jaxb-impl@default:default"/>
<setEntry value="org.mongodb.bson@default:default"/> <setEntry value="jackson-core-asl@default:default"/>
<setEntry value="org.mongodb.bson.source@default:default"/> <setEntry value="jackson-jaxrs@default:default"/>
<setEntry value="org.mongodb.driver-sync@default:default"/> <setEntry value="jackson-mapper-asl@default:default"/>
<setEntry value="org.mongodb.driver-sync@default:default"/> <setEntry value="javax.annotation@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot@3:true"/> <setEntry value="javax.validation@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot.warurl@default:default"/> <setEntry value="javax.ws.rs@default:default"/>
<setEntry value="org.hyperic.sigar@default:default"/> <setEntry value="javax.xml.soap@default:default"/>
<setEntry value="slf4j.jdk14@default:default"/> <setEntry value="javax.xml.stream@default:default"/>
<setEntry value="lz4-java@default:default"/> <setEntry value="javax.xml.ws@default:default"/>
<setEntry value="org.apache.felix.gogo.command@default:default"/> <setEntry value="javax.xml@default:default"/>
<setEntry value="org.apache.felix.gogo.runtime@default:default"/> <setEntry value="jaxb-api@default:default"/>
<setEntry value="org.apache.felix.gogo.shell@default:default"/> <setEntry value="jcl.over.slf4j@default:default"/>
<setEntry value="org.eclipse.jetty.deploy@default:default"/> <setEntry value="lz4-java@default:default"/>
<setEntry value="org.eclipse.jetty.deploy.source@default:default"/> <setEntry value="org.apache.aries.spifly.dynamic.bundle.source"/>
<setEntry value="org.eclipse.jetty.http@3:true"/> <setEntry value="org.apache.aries.spifly.dynamic.bundle@3:true"/>
<setEntry value="org.eclipse.jetty.http.source@default:default"/> <setEntry value="org.apache.commons.beanutils.source@default:default"/>
<setEntry value="org.eclipse.jetty.io@default:default"/> <setEntry value="org.apache.commons.beanutils@default:default"/>
<setEntry value="org.eclipse.jetty.io.source@default:default"/> <setEntry value="org.apache.commons.codec@default:default"/>
<setEntry value="org.eclipse.jetty.jmx@default:default"/> <setEntry value="org.apache.commons.collections4.source"/>
<setEntry value="org.eclipse.jetty.jmx.source@default:default"/> <setEntry value="org.apache.commons.collections4@default:default"/>
<setEntry value="org.eclipse.jetty.security@default:default"/> <setEntry value="org.apache.commons.collections@default:default"/>
<setEntry value="org.eclipse.jetty.security.source@default:default"/> <setEntry value="org.apache.commons.compress.source"/>
<setEntry value="org.eclipse.jetty.server@default:default"/> <setEntry value="org.apache.commons.compress@default:default"/>
<setEntry value="org.eclipse.jetty.server.source@default:default"/> <setEntry value="org.apache.commons.fileupload@default:default"/>
<setEntry value="org.eclipse.jetty.servlet@default:default"/> <setEntry value="org.apache.commons.io@default:default"/>
<setEntry value="org.eclipse.jetty.servlet.source@default:default"/> <setEntry value="org.apache.commons.lang@default:default"/>
<setEntry value="org.eclipse.jetty.util@default:default"/> <setEntry value="org.apache.commons.logging@default:default"/>
<setEntry value="org.eclipse.jetty.util.source@default:default"/> <setEntry value="org.apache.commons.math3@default:default"/>
<setEntry value="org.eclipse.jetty.util.ajax@default:default"/> <setEntry value="org.apache.commons.math@default:default"/>
<setEntry value="org.eclipse.jetty.util.ajax.source@default:default"/> <setEntry value="org.apache.felix.gogo.command@default:default"/>
<setEntry value="org.eclipse.jetty.webapp@default:default"/> <setEntry value="org.apache.felix.gogo.runtime@default:default"/>
<setEntry value="org.eclipse.jetty.webapp.source@default:default"/> <setEntry value="org.apache.felix.gogo.shell@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.api@default:default"/> <setEntry value="org.apache.geronimo.specs.geronimo-jta_1.1_spec@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.api.source@default:default"/> <setEntry value="org.apache.httpcomponents.httpclient@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.client@default:default"/> <setEntry value="org.apache.httpcomponents.httpcore@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.client.source@default:default"/> <setEntry value="org.apache.poi.ooxml.schemas@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.common@default:default"/> <setEntry value="org.apache.poi.ooxml.source"/>
<setEntry value="org.eclipse.jetty.websocket.common.source@default:default"/> <setEntry value="org.apache.poi.ooxml@default:default"/>
<setEntry value="org.eclipse.jetty.xml@default:default"/> <setEntry value="org.apache.poi.source"/>
<setEntry value="org.eclipse.jetty.xml.source@default:default"/> <setEntry value="org.apache.poi@default:default"/>
<setEntry value="slf4j.api@default:default"/> <setEntry value="org.apache.servicemix.bundles.ehcache@default:default"/>
<setEntry value="org.apache.servicemix.bundles.zxing@default:default"/> <setEntry value="org.apache.servicemix.bundles.scribe@default:default"/>
<setEntry value="org.apache.commons.io@default:default"/> <setEntry value="org.apache.servicemix.bundles.zxing@default:default"/>
<setEntry value="jcl.over.slf4j@default:default"/> <setEntry value="org.apache.shiro.core.source"/>
<setEntry value="com.sun.mail.javax.mail@default:default"/> <setEntry value="org.apache.shiro.core@default:default"/>
<setEntry value="com.rabbitmq.client@default:default"/> <setEntry value="org.apache.shiro.ehcache.source"/>
<setEntry value="com.rabbitmq.client.source@default:default"/> <setEntry value="org.apache.shiro.ehcache@default:default"/>
<setEntry value="org.apache.commons.lang@default:default"/> <setEntry value="org.apache.shiro.web.source"/>
<setEntry value="org.apache.commons.logging@default:default"/> <setEntry value="org.apache.shiro.web@default:default"/>
<setEntry value="jackson-jaxrs@default:default"/> <setEntry value="org.apache.taglibs.standard-impl@default:default"/>
<setEntry value="com.sun.jersey@default:default"/> <setEntry value="org.apache.taglibs.taglibs-standard-spec@default:default"/>
<setEntry value="javax.ws.rs@default:default"/> <setEntry value="org.apache.xalan@default:default"/>
<setEntry value="org.apache.commons.beanutils@default:default"/> <setEntry value="org.apache.xml.serializer@default:default"/>
<setEntry value="org.apache.commons.beanutils.source@default:default"/> <setEntry value="org.apache.xmlbeans@default:default"/>
<setEntry value="org.apache.servicemix.bundles.ehcache@default:default"/> <setEntry value="org.dom4j@default:default"/>
<setEntry value="org.apache.servicemix.bundles.scribe@default:default"/> <setEntry value="org.eclipse.equinox.cm@default:default"/>
<setEntry value="org.owasp.encoder@default:default"/> <setEntry value="org.eclipse.equinox.common@2:true"/>
<setEntry value="org.owasp.encoder.source@default:default"/> <setEntry value="org.eclipse.equinox.console@default:default"/>
<setEntry value="org.apache.shiro.core@default:default"/> <setEntry value="org.eclipse.equinox.event@default:default"/>
<setEntry value="org.apache.shiro.core.source@default:default"/> <setEntry value="org.eclipse.equinox.launcher@default:default"/>
<setEntry value="org.apache.shiro.ehcache@default:default"/> <setEntry value="org.eclipse.equinox.simpleconfigurator@2:true"/>
<setEntry value="org.apache.shiro.ehcache.source@default:default"/> <setEntry value="org.eclipse.jdt.core.compiler.batch@default:default"/>
<setEntry value="org.apache.shiro.web@default:default"/> <setEntry value="org.eclipse.jetty.annotations@4:true"/>
<setEntry value="org.apache.shiro.web.source@default:default"/> <setEntry value="org.eclipse.jetty.apache-jsp.source"/>
<setEntry value="jackson-core-asl@default:default"/> <setEntry value="org.eclipse.jetty.apache-jsp@4:true"/>
<setEntry value="jackson-mapper-asl@default:default"/> <setEntry value="org.eclipse.jetty.client@default:default"/>
<setEntry value="org.apache.commons.collections@default:default"/> <setEntry value="org.eclipse.jetty.deploy.source"/>
<setEntry value="org.eclipse.jetty.client@default:default"/> <setEntry value="org.eclipse.jetty.deploy@default:default"/>
<setEntry value="javax.xml@default:default"/> <setEntry value="org.eclipse.jetty.http.source"/>
<setEntry value="com.sun.activation.javax.activation@default:default"/> <setEntry value="org.eclipse.jetty.http@3:true"/>
<setEntry value="org.eclipse.equinox.common@2:true"/> <setEntry value="org.eclipse.jetty.io.source"/>
<setEntry value="org.eclipse.equinox.console@default:default"/> <setEntry value="org.eclipse.jetty.io@default:default"/>
<setEntry value="org.eclipse.equinox.launcher@default:default"/> <setEntry value="org.eclipse.jetty.jmx.source"/>
<setEntry value="org.eclipse.equinox.simpleconfigurator@2:true"/> <setEntry value="org.eclipse.jetty.jmx@default:default"/>
<setEntry value="org.eclipse.osgi@-1:true"/> <setEntry value="org.eclipse.jetty.jndi@default:default"/>
<setEntry value="org.eclipse.osgi.source@default:default"/> <setEntry value="org.eclipse.jetty.osgi-servlet-api@default:default"/>
<setEntry value="org.osgi.util.promise@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot.jsp.source"/>
<setEntry value="org.osgi.util.promise.source@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot.jsp@default:false"/>
<setEntry value="org.osgi.util.function@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot.warurl@default:default"/>
<setEntry value="org.osgi.util.function.source@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot@3:true"/>
<setEntry value="org.osgi.util.measurement@default:default"/> <setEntry value="org.eclipse.jetty.plus@default:default"/>
<setEntry value="org.osgi.util.measurement.source@default:default"/> <setEntry value="org.eclipse.jetty.security.source"/>
<setEntry value="org.osgi.util.position@default:default"/> <setEntry value="org.eclipse.jetty.security@default:default"/>
<setEntry value="org.osgi.util.position.source@default:default"/> <setEntry value="org.eclipse.jetty.server.source"/>
<setEntry value="org.osgi.util.xml@default:default"/> <setEntry value="org.eclipse.jetty.server@default:default"/>
<setEntry value="org.osgi.util.xml.source@default:default"/> <setEntry value="org.eclipse.jetty.servlet.source"/>
<setEntry value="org.eclipse.osgi.services@default:default"/> <setEntry value="org.eclipse.jetty.servlet@default:default"/>
<setEntry value="org.eclipse.osgi.services.source@default:default"/> <setEntry value="org.eclipse.jetty.util.ajax.source"/>
<setEntry value="org.eclipse.equinox.cm@default:default"/> <setEntry value="org.eclipse.jetty.util.ajax@default:default"/>
<setEntry value="com.sun.istack.commons-runtime@default:default"/> <setEntry value="org.eclipse.jetty.util.source"/>
<setEntry value="jaxb-api@default:default"/> <setEntry value="org.eclipse.jetty.util@default:default"/>
<setEntry value="com.sun.xml.bind.jaxb-impl@default:default"/> <setEntry value="org.eclipse.jetty.webapp.source"/>
<setEntry value="javax.xml.stream@default:default"/> <setEntry value="org.eclipse.jetty.webapp@default:default"/>
<setEntry value="javax.xml.ws@default:default"/> <setEntry value="org.eclipse.jetty.websocket.api.source"/>
<setEntry value="javax.xml.soap@default:default"/> <setEntry value="org.eclipse.jetty.websocket.api@default:default"/>
<setEntry value="org.eclipse.osgi.util@default:default"/> <setEntry value="org.eclipse.jetty.websocket.client.source"/>
<setEntry value="org.eclipse.osgi.util.source@default:default"/> <setEntry value="org.eclipse.jetty.websocket.client@default:default"/>
<setEntry value="com.chargebee.chargebee-java@default:default"/> <setEntry value="org.eclipse.jetty.websocket.common.source"/>
<setEntry value="com.jcraft.jsch@default:default"/> <setEntry value="org.eclipse.jetty.websocket.common@default:default"/>
<setEntry value="com.amazon.aws.aws-java-api@default:default"/> <setEntry value="org.eclipse.jetty.xml.source"/>
<setEntry value="com.amazon.aws.aws-java-api.source@default:default"/> <setEntry value="org.eclipse.jetty.xml@default:default"/>
<setEntry value="org.objectweb.asm@default:default"/> <setEntry value="org.eclipse.osgi.services.source"/>
<setEntry value="org.objectweb.asm.commons@default:default"/> <setEntry value="org.eclipse.osgi.services@default:default"/>
<setEntry value="org.objectweb.asm.analysis@default:default"/> <setEntry value="org.eclipse.osgi.source"/>
<setEntry value="org.objectweb.asm.tree@default:default"/> <setEntry value="org.eclipse.osgi.util.source"/>
<setEntry value="org.objectweb.asm.util@default:default"/> <setEntry value="org.eclipse.osgi.util@default:default"/>
<setEntry value="org.objectweb.asm.source@default:default"/> <setEntry value="org.eclipse.osgi@-1:true"/>
<setEntry value="org.objectweb.asm.analysis.source@default:default"/> <setEntry value="org.hyperic.sigar@default:default"/>
<setEntry value="org.objectweb.asm.commons.source@default:default"/> <setEntry value="org.jvnet.mimepull@default:default"/>
<setEntry value="org.objectweb.asm.tree.source@default:default"/> <setEntry value="org.mongodb.bson.source"/>
<setEntry value="org.objectweb.asm.util.source@default:default"/> <setEntry value="org.mongodb.bson@default:default"/>
<setEntry value="org.eclipse.jetty.apache-jsp@4:true"/> <setEntry value="org.mongodb.driver-core.source"/>
<setEntry value="org.eclipse.jetty.apache-jsp.source@default:default"/> <setEntry value="org.mongodb.driver-core@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot.jsp@default:default"/> <setEntry value="org.mongodb.driver-sync@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot.jsp.source@default:default"/> <setEntry value="org.mortbay.jasper.apache-el@default:default"/>
<setEntry value="org.apache.geronimo.specs.geronimo-jta_1.1_spec@default:default"/> <setEntry value="org.mortbay.jasper.apache-jsp@default:default"/>
<setEntry value="org.apache.aries.spifly.dynamic.bundle@3:true"/> <setEntry value="org.objectweb.asm.analysis.source"/>
<setEntry value="org.apache.aries.spifly.dynamic.bundle.source@default:default"/> <setEntry value="org.objectweb.asm.analysis@default:default"/>
<setEntry value="org.mortbay.jasper.apache-el@default:default"/> <setEntry value="org.objectweb.asm.commons.source"/>
<setEntry value="org.mortbay.jasper.apache-jsp@default:default"/> <setEntry value="org.objectweb.asm.commons@default:default"/>
<setEntry value="org.eclipse.jdt.core.compiler.batch@default:default"/> <setEntry value="org.objectweb.asm.source"/>
<setEntry value="org.apache.taglibs.standard-impl@default:default"/> <setEntry value="org.objectweb.asm.tree.source"/>
<setEntry value="org.apache.taglibs.taglibs-standard-spec@default:default"/> <setEntry value="org.objectweb.asm.tree@default:default"/>
<setEntry value="javax.annotation@default:default"/> <setEntry value="org.objectweb.asm.util.source"/>
<setEntry value="org.eclipse.jetty.osgi-servlet-api@default:default"/> <setEntry value="org.objectweb.asm.util@default:default"/>
<setEntry value="org.apache.xalan@default:default"/> <setEntry value="org.objectweb.asm@default:default"/>
<setEntry value="org.apache.xml.serializer@default:default"/> <setEntry value="org.osgi.service.packageadmin@default:default"/>
<setEntry value="org.eclipse.equinox.event@default:default"/> <setEntry value="org.osgi.service.url@default:default"/>
<setEntry value="org.eclipse.jetty.annotations@4:true"/> <setEntry value="org.osgi.util.function.source"/>
<setEntry value="org.eclipse.jetty.jndi@default:default"/> <setEntry value="org.osgi.util.function@default:default"/>
<setEntry value="org.eclipse.jetty.plus@default:default"/> <setEntry value="org.osgi.util.measurement.source"/>
<setEntry value="com.sap.db.jdbc@default:default"/> <setEntry value="org.osgi.util.measurement@default:default"/>
<setEntry value="com.sap.db.jdbc.source@default:default"/> <setEntry value="org.osgi.util.position.source"/>
<setEntry value="org.osgi.service.packageadmin@default:default"/> <setEntry value="org.osgi.util.position@default:default"/>
<setEntry value="org.osgi.service.url@default:default"/> <setEntry value="org.osgi.util.promise.source"/>
<setEntry value="com.github.haifengl.smile-core@default:default"/> <setEntry value="org.osgi.util.promise@default:default"/>
<setEntry value="com.github.haifengl.smile-core.source@default:default"/> <setEntry value="org.osgi.util.xml.source"/>
<setEntry value="com.github.haifengl.smile-data@default:default"/> <setEntry value="org.osgi.util.xml@default:default"/>
<setEntry value="com.github.haifengl.smile-data.source@default:default"/> <setEntry value="org.owasp.encoder.source"/>
<setEntry value="com.github.haifengl.smile-graph@default:default"/> <setEntry value="org.owasp.encoder@default:default"/>
<setEntry value="com.github.haifengl.smile-graph.source@default:default"/> <setEntry value="routeconverter@default:default"/>
<setEntry value="com.github.haifengl.smile-math@default:default"/> <setEntry value="slf4j.api@default:default"/>
<setEntry value="com.github.haifengl.smile-math.source@default:default"/> <setEntry value="slf4j.jdk14@default:false"/>
<setEntry value="com.google.gson@default:default"/> </setAttribute>
<setEntry value="com.google.gson.source@default:default"/>
</setAttribute>
<setAttribute key="selected_workspace_bundles"> <setAttribute key="selected_workspace_bundles">
<setEntry value="com.sap.sailing.geocoding@default:default"/> <setEntry value="com.google.gwt.servlet@default:default"/>
<setEntry value="com.sap.sailing.domain.common@default:default"/> <setEntry value="com.googlecode.java-diff-utils@default:default"/>
<setEntry value="com.sap.sailing.domain@default:default"/> <setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
<setEntry value="com.sap.sailing.news@4:true"/> <setEntry value="com.sap.sailing.competitorimport@default:default"/>
<setEntry value="com.sap.sailing.domain.tractracadapter@5:true"/> <setEntry value="com.sap.sailing.dashboards.gwt@6:true"/>
<setEntry value="com.sap.sailing.expeditionconnector@default:default"/> <setEntry value="com.sap.sailing.datamining.provider@default:default"/>
<setEntry value="com.sap.sailing.domain.windfinderadapter@4:true"/> <setEntry value="com.sap.sailing.datamining.shared@default:default"/>
<setEntry value="com.sap.sailing.server@5:true"/> <setEntry value="com.sap.sailing.datamining@5:true"/>
<setEntry value="com.sap.sailing.server.gateway@5:true"/> <setEntry value="com.sap.sailing.declination@default:default"/>
<setEntry value="com.sap.sailing.server.gateway.interfaces@default:default"/> <setEntry value="com.sap.sailing.domain.bravoadapter@5:true"/>
<setEntry value="com.tractrac.clientmodule@default:default"/> <setEntry value="com.sap.sailing.domain.common@default:default"/>
<setEntry value="com.sap.sailing.declination@default:default"/> <setEntry value="com.sap.sailing.domain.deckmanadapter@5:true"/>
<setEntry value="com.sap.sailing.domain.persistence@default:default"/> <setEntry value="com.sap.sailing.domain.expeditionadapter@5:true"/>
<setEntry value="com.sap.sailing.domain.swisstimingadapter@5:true"/> <setEntry value="com.sap.sailing.domain.igtimiadapter.gateway@5:true"/>
<setEntry value="com.sap.sailing.domain.swisstimingadapter.persistence@4:true"/> <setEntry value="com.sap.sailing.domain.igtimiadapter.persistence@default:default"/>
<setEntry value="com.sap.sailing.domain.swisstimingreplayadapter@4:true"/> <setEntry value="com.sap.sailing.domain.igtimiadapter@4:true"/>
<setEntry value="com.sap.sailing.domain.tractracadapter.persistence@4:true"/> <setEntry value="com.sap.sailing.domain.oceanraceadapter@5:true"/>
<setEntry value="com.sap.sailing.gwt.ui@6:true"/> <setEntry value="com.sap.sailing.domain.persistence@default:default"/>
<setEntry value="com.sap.sailing.udpconnector@default:default"/> <setEntry value="com.sap.sailing.domain.racelogtrackingadapter@4:true"/>
<setEntry value="com.sap.sailing.simulator@default:default"/> <setEntry value="com.sap.sailing.domain.shared.android@default:default"/>
<setEntry value="com.sap.sailing.www@5:true"/> <setEntry value="com.sap.sailing.domain.swisstimingadapter.persistence@4:true"/>
<setEntry value="com.sap.sailing.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.swisstimingadapter@5:true"/>
<setEntry value="com.sap.sailing.kiworesultimport@4:true"/> <setEntry value="com.sap.sailing.domain.swisstimingreplayadapter@4:true"/>
<setEntry value="com.sap.sailing.ess40.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.tractracadapter.persistence@4:true"/>
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.tractracadapter@5:true"/>
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.windfinderadapter@4:true"/>
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.yellowbrickadapter.persistence@4:true"/>
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.yellowbrickadapter@5:true"/>
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain@default:default"/>
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/> <setEntry value="com.sap.sailing.ess40.resultimport@4:true"/>
<setEntry value="com.sap.sailing.velum.resultimport@4:true"/> <setEntry value="com.sap.sailing.expeditionconnector.common@default:default"/>
<setEntry value="com.sap.sailing.monitoring@7:true"/> <setEntry value="com.sap.sailing.expeditionconnector.persistence@4:true"/>
<setEntry value="com.sap.sailing.xrr.resultimport@4:true"/> <setEntry value="com.sap.sailing.expeditionconnector@default:default"/>
<setEntry value="com.sap.sailing.domain.igtimiadapter@4:true"/> <setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
<setEntry value="com.sap.sailing.domain.igtimiadapter.persistence@default:default"/> <setEntry value="com.sap.sailing.geocoding@default:default"/>
<setEntry value="com.sap.sailing.domain.racelogtrackingadapter@4:true"/> <setEntry value="com.sap.sailing.grib@default:default"/>
<setEntry value="com.sap.sailing.domain.deckmanadapter@5:true"/> <setEntry value="com.sap.sailing.gwt.ui@6:true"/>
<setEntry value="com.sap.sailing.domain.oceanraceadapter@5:true"/> <setEntry value="com.sap.sailing.hanaexport@5:true"/>
<setEntry value="com.sap.sailing.domain.yellowbrickadapter@5:true"/> <setEntry value="com.sap.sailing.kiworesultimport@4:true"/>
<setEntry value="com.sap.sailing.domain.yellowbrickadapter.persistence@4:true"/> <setEntry value="com.sap.sailing.landscape.common@default:default"/>
<setEntry value="com.sap.sailing.xrr.structureimport@default:default"/> <setEntry value="com.sap.sailing.landscape.gateway@5:true"/>
<setEntry value="com.sap.sailing.server.gateway.serialization.shared.android@default:default"/> <setEntry value="com.sap.sailing.landscape.ui@default:default"/>
<setEntry value="com.sap.sailing.server.gateway.serialization@default:default"/> <setEntry value="com.sap.sailing.landscape@default:default"/>
<setEntry value="com.sap.sailing.dashboards.gwt@6:true"/> <setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
<setEntry value="com.sap.sailing.dashboards.gwt@6:true"/> <setEntry value="com.sap.sailing.manage2sail@default:default"/>
<setEntry value="com.sap.sailing.datamining@5:true"/> <setEntry value="com.sap.sailing.monitoring@7:true"/>
<setEntry value="com.sap.sailing.datamining.shared@default:default"/> <setEntry value="com.sap.sailing.news@4:true"/>
<setEntry value="com.sap.sailing.polars@5:true"/> <setEntry value="com.sap.sailing.nmeaconnector@default:default"/>
<setEntry value="com.sap.sailing.windestimation@5:true"/> <setEntry value="com.sap.sailing.polars.datamining.shared@default:default"/>
<setEntry value="com.sap.sailing.polars.datamining@5:true"/> <setEntry value="com.sap.sailing.polars.datamining@5:true"/>
<setEntry value="com.sap.sailing.domain.shared.android@default:default"/> <setEntry value="com.sap.sailing.polars@5:true"/>
<setEntry value="com.sap.sailing.manage2sail@default:default"/> <setEntry value="com.sap.sailing.resultimport@4:true"/>
<setEntry value="com.sap.sailing.polars.datamining.shared@default:default"/> <setEntry value="com.sap.sailing.routeconverterjava11extension@default:false"/>
<setEntry value="com.sap.sailing.xrr.schema@default:default"/> <setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
<setEntry value="com.sap.sailing.server.trackfiles@default:default"/> <setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
<setEntry value="com.sap.sailing.competitorimport@default:default"/> <setEntry value="com.sap.sailing.server.gateway.interfaces@default:default"/>
<setEntry value="com.sap.sailing.datamining.provider@default:default"/> <setEntry value="com.sap.sailing.server.gateway.serialization.shared.android@default:default"/>
<setEntry value="com.sap.sailing.grib@default:default"/> <setEntry value="com.sap.sailing.server.gateway.serialization@default:default"/>
<setEntry value="com.sap.sailing.nmeaconnector@default:default"/> <setEntry value="com.sap.sailing.server.gateway@5:true"/>
<setEntry value="com.sap.sailing.domain.expeditionadapter@5:true"/> <setEntry value="com.sap.sailing.server.interface@default:default"/>
<setEntry value="com.sap.sailing.expeditionconnector.persistence@4:true"/> <setEntry value="com.sap.sailing.server.trackfiles@default:default"/>
<setEntry value="com.sap.sailing.expeditionconnector.common@default:default"/> <setEntry value="com.sap.sailing.server@5:true"/>
<setEntry value="com.sap.sailing.domain.bravoadapter@5:true"/> <setEntry value="com.sap.sailing.shared.persistence@default:default"/>
<setEntry value="net.sf.marineapi@default:default"/> <setEntry value="com.sap.sailing.shared.server.gateway@5:true"/>
<setEntry value="com.sap.sailing.routeconverterjava11extension@default:default"/> <setEntry value="com.sap.sailing.shared.server@5:true"/>
<setEntry value="com.sap.sailing.server.interface@default:default"/> <setEntry value="com.sap.sailing.simulator@default:default"/>
<setEntry value="com.sap.sse.datamining.ui@default:default"/> <setEntry value="com.sap.sailing.udpconnector@default:default"/>
<setEntry value="com.sap.sailing.domain.igtimiadapter.gateway@5:true"/> <setEntry value="com.sap.sailing.velum.resultimport@4:true"/>
<setEntry value="com.sap.sailing.shared.server@5:true"/> <setEntry value="com.sap.sailing.windestimation@5:true"/>
<setEntry value="com.sap.sailing.shared.server.gateway@5:true"/> <setEntry value="com.sap.sailing.www@5:true"/>
<setEntry value="com.sap.sailing.shared.persistence@default:default"/> <setEntry value="com.sap.sailing.xrr.resultimport@4:true"/>
<setEntry value="com.sap.sailing.landscape@default:default"/> <setEntry value="com.sap.sailing.xrr.schema@default:default"/>
<setEntry value="com.sap.sailing.landscape.gateway@5:true"/> <setEntry value="com.sap.sailing.xrr.structureimport@default:default"/>
<setEntry value="com.sap.sailing.landscape.common@default:default"/> <setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
<setEntry value="com.sap.sailing.landscape.ui@default:default"/> <setEntry value="com.sap.sse.common@default:default"/>
<setEntry value="com.sap.sailing.hanaexport@5:true"/> <setEntry value="com.sap.sse.datamining.annotations@default:default"/>
<setEntry value="com.tractrac.clientmodule@default:default"/> <setEntry value="com.sap.sse.datamining.shared@default:default"/>
<setEntry value="com.sap.sse.gwt@default:default"/> <setEntry value="com.sap.sse.datamining.ui@default:default"/>
<setEntry value="com.google.gwt.servlet@default:default"/> <setEntry value="com.sap.sse.datamining@default:default"/>
<setEntry value="com.sap.sse.security@default:default"/> <setEntry value="com.sap.sse.debranding@default:default"/>
<setEntry value="com.sap.sse.security.ui@6:true"/> <setEntry value="com.sap.sse.filestorage@4:true"/>
<setEntry value="com.sap.sse.security.userstore.mongodb@4:true"/> <setEntry value="com.sap.sse.gwt.adminconsole@default:default"/>
<setEntry value="com.sap.sse@default:default"/> <setEntry value="com.sap.sse.gwt@default:default"/>
<setEntry value="com.sap.sse.common@default:default"/> <setEntry value="com.sap.sse.landscape.aws.common@default:default"/>
<setEntry value="com.sap.sse.datamining@default:default"/> <setEntry value="com.sap.sse.landscape.aws.persistence@default:default"/>
<setEntry value="com.sap.sse.datamining.annotations@default:default"/> <setEntry value="com.sap.sse.landscape.aws@4:true"/>
<setEntry value="com.sap.sse.datamining.shared@default:default"/> <setEntry value="com.sap.sse.landscape.common@default:default"/>
<setEntry value="com.sap.sse.gwt.adminconsole@default:default"/> <setEntry value="com.sap.sse.landscape@default:default"/>
<setEntry value="com.sap.sse.mongodb@default:default"/> <setEntry value="com.sap.sse.mail@5:true"/>
<setEntry value="com.sap.sse.operationaltransformation@default:default"/> <setEntry value="com.sap.sse.mongodb@default:default"/>
<setEntry value="com.sap.sse.replication@6:true"/> <setEntry value="com.sap.sse.operationaltransformation@default:default"/>
<setEntry value="com.sap.sse.filestorage@4:true"/> <setEntry value="com.sap.sse.replication.interfaces@default:default"/>
<setEntry value="com.sap.sse.shared.android@default:default"/> <setEntry value="com.sap.sse.replication.persistence@default:default"/>
<setEntry value="com.sap.sse.mail@5:true"/> <setEntry value="com.sap.sse.replication@6:true"/>
<setEntry value="com.sap.sse.threadmanager@default:default"/> <setEntry value="com.sap.sse.security.common@default:default"/>
<setEntry value="com.sap.sse.security.common@default:default"/> <setEntry value="com.sap.sse.security.interface@default:default"/>
<setEntry value="org.json.simple@default:default"/> <setEntry value="com.sap.sse.security.persistence@default:default"/>
<setEntry value="org.moxieapps.gwt.highcharts@default:default"/> <setEntry value="com.sap.sse.security.ui@6:true"/>
<setEntry value="com.googlecode.java-diff-utils@default:default"/> <setEntry value="com.sap.sse.security.userstore.mongodb@4:true"/>
<setEntry value="org.mp4parser.isoparser@default:default"/> <setEntry value="com.sap.sse.security@default:default"/>
<setEntry value="com.sap.sse.replication.interfaces@default:default"/> <setEntry value="com.sap.sse.shared.android@default:default"/>
<setEntry value="com.sap.sse.security.persistence@default:default"/> <setEntry value="com.sap.sse.threadmanager@default:default"/>
<setEntry value="com.sap.sse.security.interface@default:default"/> <setEntry value="com.sap.sse@default:default"/>
<setEntry value="com.sap.sse.replication.persistence@default:default"/> <setEntry value="com.tractrac.clientmodule@default:default"/>
<setEntry value="com.sap.sse.landscape.common@default:default"/> <setEntry value="elemental2@default:default"/>
<setEntry value="com.sap.sse.landscape@default:default"/> <setEntry value="net.sf.marineapi@default:default"/>
<setEntry value="com.sap.sse.landscape.aws@4:true"/> <setEntry value="org.json.simple@default:default"/>
<setEntry value="com.sap.sse.landscape.aws.common@default:default"/> <setEntry value="org.moxieapps.gwt.highcharts@default:default"/>
<setEntry value="com.sap.sse.landscape.aws.persistence@default:default"/> <setEntry value="org.mp4parser.isoparser@default:default"/>
<setEntry value="com.sap.sse.debranding@default:default"/> </setAttribute>
<setEntry value="elemental2@default:default"/>
</setAttribute>
<booleanAttribute key="show_selected_only" value="false"/> <booleanAttribute key="show_selected_only" value="false"/>
<booleanAttribute key="tracing" value="false"/> <booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/> <booleanAttribute key="useCustomFeatures" value="false"/>
@@ -13,6 +13,7 @@
<intAttribute key="default_start_level" value="4"/> <intAttribute key="default_start_level" value="4"/>
<setAttribute key="deselected_workspace_bundles"/> <setAttribute key="deselected_workspace_bundles"/>
<booleanAttribute key="includeOptional" value="true"/> <booleanAttribute key="includeOptional" value="true"/>
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
@@ -31,291 +32,286 @@
<stringAttribute key="profilingTraceType-PERFORMANCE_HOTSPOT_TRACE" value="KEY_IGNORE_SLEEPING_THREADS%CTX_KEY%true%CTX_ENTRY%KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/> <stringAttribute key="profilingTraceType-PERFORMANCE_HOTSPOT_TRACE" value="KEY_IGNORE_SLEEPING_THREADS%CTX_KEY%true%CTX_ENTRY%KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/>
<stringAttribute key="profilingTraceType-SYNCHRONIZATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/> <stringAttribute key="profilingTraceType-SYNCHRONIZATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/>
<setAttribute key="selected_target_bundles"> <setAttribute key="selected_target_bundles">
<setEntry value="routeconverter@default:default"/> <setEntry value="com.amazon.aws.aws-java-api.source"/>
<setEntry value="org.apache.commons.codec@default:default"/> <setEntry value="com.amazon.aws.aws-java-api@default:default"/>
<setEntry value="org.apache.poi@default:default"/> <setEntry value="com.chargebee.chargebee-java@default:default"/>
<setEntry value="org.apache.poi.ooxml@default:default"/> <setEntry value="com.github.haifengl.smile-core.source"/>
<setEntry value="org.apache.poi.ooxml.schemas@default:default"/> <setEntry value="com.github.haifengl.smile-core@default:default"/>
<setEntry value="org.apache.commons.collections4@default:default"/> <setEntry value="com.github.haifengl.smile-data.source"/>
<setEntry value="org.apache.commons.compress@default:default"/> <setEntry value="com.github.haifengl.smile-data@default:default"/>
<setEntry value="org.apache.poi.source@default:default"/> <setEntry value="com.github.haifengl.smile-graph.source"/>
<setEntry value="org.apache.poi.ooxml.source@default:default"/> <setEntry value="com.github.haifengl.smile-graph@default:default"/>
<setEntry value="org.apache.commons.collections4.source@default:default"/> <setEntry value="com.github.haifengl.smile-math.source"/>
<setEntry value="org.apache.commons.compress.source@default:default"/> <setEntry value="com.github.haifengl.smile-math@default:default"/>
<setEntry value="org.dom4j@default:default"/> <setEntry value="com.google.gson.source"/>
<setEntry value="org.apache.xmlbeans@default:default"/> <setEntry value="com.google.gson@default:default"/>
<setEntry value="org.apache.commons.math@default:default"/> <setEntry value="com.jcraft.jsch@default:default"/>
<setEntry value="org.apache.httpcomponents.httpclient@default:default"/> <setEntry value="com.rabbitmq.client.source"/>
<setEntry value="org.apache.httpcomponents.httpcore@default:default"/> <setEntry value="com.rabbitmq.client@default:default"/>
<setEntry value="org.hyperic.sigar@default:default"/> <setEntry value="com.sap.db.jdbc.source"/>
<setEntry value="com.sun.jersey.contribs.jersey-multipart@default:default"/> <setEntry value="com.sap.db.jdbc@default:default"/>
<setEntry value="javax.validation@default:default"/> <setEntry value="com.sun.activation.javax.activation@default:default"/>
<setEntry value="org.apache.commons.fileupload@default:default"/> <setEntry value="com.sun.istack.commons-runtime@default:default"/>
<setEntry value="org.jvnet.mimepull@default:default"/> <setEntry value="com.sun.jersey.contribs.jersey-multipart@default:default"/>
<setEntry value="org.apache.commons.math3@default:default"/> <setEntry value="com.sun.jersey@default:default"/>
<setEntry value="org.mongodb.driver-core@default:default"/> <setEntry value="com.sun.mail.javax.mail@default:default"/>
<setEntry value="org.mongodb.driver-core.source@default:default"/> <setEntry value="com.sun.xml.bind.jaxb-impl@default:default"/>
<setEntry value="org.mongodb.bson@default:default"/> <setEntry value="jackson-core-asl@default:default"/>
<setEntry value="org.mongodb.bson.source@default:default"/> <setEntry value="jackson-jaxrs@default:default"/>
<setEntry value="org.mongodb.driver-sync@default:default"/> <setEntry value="jackson-mapper-asl@default:default"/>
<setEntry value="org.mongodb.driver-sync@default:default"/> <setEntry value="javax.annotation@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot@3:true"/> <setEntry value="javax.validation@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot.warurl@default:default"/> <setEntry value="javax.ws.rs@default:default"/>
<setEntry value="org.hyperic.sigar@default:default"/> <setEntry value="javax.xml.soap@default:default"/>
<setEntry value="slf4j.jdk14@default:default"/> <setEntry value="javax.xml.stream@default:default"/>
<setEntry value="lz4-java@default:default"/> <setEntry value="javax.xml.ws@default:default"/>
<setEntry value="org.apache.felix.gogo.command@default:default"/> <setEntry value="javax.xml@default:default"/>
<setEntry value="org.apache.felix.gogo.runtime@default:default"/> <setEntry value="jaxb-api@default:default"/>
<setEntry value="org.apache.felix.gogo.shell@default:default"/> <setEntry value="jcl.over.slf4j@default:default"/>
<setEntry value="org.eclipse.jetty.deploy@default:default"/> <setEntry value="lz4-java@default:default"/>
<setEntry value="org.eclipse.jetty.deploy.source@default:default"/> <setEntry value="org.apache.aries.spifly.dynamic.bundle.source"/>
<setEntry value="org.eclipse.jetty.http@3:true"/> <setEntry value="org.apache.aries.spifly.dynamic.bundle@3:true"/>
<setEntry value="org.eclipse.jetty.http.source@default:default"/> <setEntry value="org.apache.commons.beanutils.source@default:default"/>
<setEntry value="org.eclipse.jetty.io@default:default"/> <setEntry value="org.apache.commons.beanutils@default:default"/>
<setEntry value="org.eclipse.jetty.io.source@default:default"/> <setEntry value="org.apache.commons.codec@default:default"/>
<setEntry value="org.eclipse.jetty.jmx@default:default"/> <setEntry value="org.apache.commons.collections4.source"/>
<setEntry value="org.eclipse.jetty.jmx.source@default:default"/> <setEntry value="org.apache.commons.collections4@default:default"/>
<setEntry value="org.eclipse.jetty.security@default:default"/> <setEntry value="org.apache.commons.collections@default:default"/>
<setEntry value="org.eclipse.jetty.security.source@default:default"/> <setEntry value="org.apache.commons.compress.source"/>
<setEntry value="org.eclipse.jetty.server@default:default"/> <setEntry value="org.apache.commons.compress@default:default"/>
<setEntry value="org.eclipse.jetty.server.source@default:default"/> <setEntry value="org.apache.commons.fileupload@default:default"/>
<setEntry value="org.eclipse.jetty.servlet@default:default"/> <setEntry value="org.apache.commons.io@default:default"/>
<setEntry value="org.eclipse.jetty.servlet.source@default:default"/> <setEntry value="org.apache.commons.lang@default:default"/>
<setEntry value="org.eclipse.jetty.util@default:default"/> <setEntry value="org.apache.commons.logging@default:default"/>
<setEntry value="org.eclipse.jetty.util.source@default:default"/> <setEntry value="org.apache.commons.math3@default:default"/>
<setEntry value="org.eclipse.jetty.util.ajax@default:default"/> <setEntry value="org.apache.commons.math@default:default"/>
<setEntry value="org.eclipse.jetty.util.ajax.source@default:default"/> <setEntry value="org.apache.felix.gogo.command@default:default"/>
<setEntry value="org.eclipse.jetty.webapp@default:default"/> <setEntry value="org.apache.felix.gogo.runtime@default:default"/>
<setEntry value="org.eclipse.jetty.webapp.source@default:default"/> <setEntry value="org.apache.felix.gogo.shell@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.api@default:default"/> <setEntry value="org.apache.geronimo.specs.geronimo-jta_1.1_spec@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.api.source@default:default"/> <setEntry value="org.apache.httpcomponents.httpclient@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.client@default:default"/> <setEntry value="org.apache.httpcomponents.httpcore@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.client.source@default:default"/> <setEntry value="org.apache.poi.ooxml.schemas@default:default"/>
<setEntry value="org.eclipse.jetty.websocket.common@default:default"/> <setEntry value="org.apache.poi.ooxml.source"/>
<setEntry value="org.eclipse.jetty.websocket.common.source@default:default"/> <setEntry value="org.apache.poi.ooxml@default:default"/>
<setEntry value="org.eclipse.jetty.xml@default:default"/> <setEntry value="org.apache.poi.source"/>
<setEntry value="org.eclipse.jetty.xml.source@default:default"/> <setEntry value="org.apache.poi@default:default"/>
<setEntry value="slf4j.api@default:default"/> <setEntry value="org.apache.servicemix.bundles.ehcache@default:default"/>
<setEntry value="org.apache.servicemix.bundles.zxing@default:default"/> <setEntry value="org.apache.servicemix.bundles.scribe@default:default"/>
<setEntry value="org.apache.commons.io@default:default"/> <setEntry value="org.apache.servicemix.bundles.zxing@default:default"/>
<setEntry value="jcl.over.slf4j@default:default"/> <setEntry value="org.apache.shiro.core.source"/>
<setEntry value="com.sun.mail.javax.mail@default:default"/> <setEntry value="org.apache.shiro.core@default:default"/>
<setEntry value="com.rabbitmq.client@default:default"/> <setEntry value="org.apache.shiro.ehcache.source"/>
<setEntry value="com.rabbitmq.client.source@default:default"/> <setEntry value="org.apache.shiro.ehcache@default:default"/>
<setEntry value="org.apache.commons.lang@default:default"/> <setEntry value="org.apache.shiro.web.source"/>
<setEntry value="org.apache.commons.logging@default:default"/> <setEntry value="org.apache.shiro.web@default:default"/>
<setEntry value="jackson-jaxrs@default:default"/> <setEntry value="org.apache.taglibs.standard-impl@default:default"/>
<setEntry value="com.sun.jersey@default:default"/> <setEntry value="org.apache.taglibs.taglibs-standard-spec@default:default"/>
<setEntry value="javax.ws.rs@default:default"/> <setEntry value="org.apache.xalan@default:default"/>
<setEntry value="org.apache.commons.beanutils@default:default"/> <setEntry value="org.apache.xml.serializer@default:default"/>
<setEntry value="org.apache.commons.beanutils.source@default:default"/> <setEntry value="org.apache.xmlbeans@default:default"/>
<setEntry value="org.apache.servicemix.bundles.ehcache@default:default"/> <setEntry value="org.dom4j@default:default"/>
<setEntry value="org.apache.servicemix.bundles.scribe@default:default"/> <setEntry value="org.eclipse.equinox.cm@default:default"/>
<setEntry value="org.owasp.encoder@default:default"/> <setEntry value="org.eclipse.equinox.common@2:true"/>
<setEntry value="org.owasp.encoder.source@default:default"/> <setEntry value="org.eclipse.equinox.console@default:default"/>
<setEntry value="org.apache.shiro.core@default:default"/> <setEntry value="org.eclipse.equinox.event@default:default"/>
<setEntry value="org.apache.shiro.core.source@default:default"/> <setEntry value="org.eclipse.equinox.launcher@default:default"/>
<setEntry value="org.apache.shiro.ehcache@default:default"/> <setEntry value="org.eclipse.equinox.simpleconfigurator@2:true"/>
<setEntry value="org.apache.shiro.ehcache.source@default:default"/> <setEntry value="org.eclipse.jdt.core.compiler.batch@default:default"/>
<setEntry value="org.apache.shiro.web@default:default"/> <setEntry value="org.eclipse.jetty.annotations@4:true"/>
<setEntry value="org.apache.shiro.web.source@default:default"/> <setEntry value="org.eclipse.jetty.apache-jsp.source"/>
<setEntry value="jackson-core-asl@default:default"/> <setEntry value="org.eclipse.jetty.apache-jsp@4:true"/>
<setEntry value="jackson-mapper-asl@default:default"/> <setEntry value="org.eclipse.jetty.client@default:default"/>
<setEntry value="org.apache.commons.collections@default:default"/> <setEntry value="org.eclipse.jetty.deploy.source"/>
<setEntry value="org.eclipse.jetty.client@default:default"/> <setEntry value="org.eclipse.jetty.deploy@default:default"/>
<setEntry value="javax.xml@default:default"/> <setEntry value="org.eclipse.jetty.http.source"/>
<setEntry value="com.sun.activation.javax.activation@default:default"/> <setEntry value="org.eclipse.jetty.http@3:true"/>
<setEntry value="org.eclipse.equinox.common@2:true"/> <setEntry value="org.eclipse.jetty.io.source"/>
<setEntry value="org.eclipse.equinox.console@default:default"/> <setEntry value="org.eclipse.jetty.io@default:default"/>
<setEntry value="org.eclipse.equinox.launcher@default:default"/> <setEntry value="org.eclipse.jetty.jmx.source"/>
<setEntry value="org.eclipse.equinox.simpleconfigurator@2:true"/> <setEntry value="org.eclipse.jetty.jmx@default:default"/>
<setEntry value="org.eclipse.osgi@-1:true"/> <setEntry value="org.eclipse.jetty.jndi@default:default"/>
<setEntry value="org.eclipse.osgi.source@default:default"/> <setEntry value="org.eclipse.jetty.osgi-servlet-api@default:default"/>
<setEntry value="org.osgi.util.promise@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot.jsp.source"/>
<setEntry value="org.osgi.util.promise.source@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot.jsp@default:false"/>
<setEntry value="org.osgi.util.function@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot.warurl@default:default"/>
<setEntry value="org.osgi.util.function.source@default:default"/> <setEntry value="org.eclipse.jetty.osgi.boot@3:true"/>
<setEntry value="org.osgi.util.measurement@default:default"/> <setEntry value="org.eclipse.jetty.plus@default:default"/>
<setEntry value="org.osgi.util.measurement.source@default:default"/> <setEntry value="org.eclipse.jetty.security.source"/>
<setEntry value="org.osgi.util.position@default:default"/> <setEntry value="org.eclipse.jetty.security@default:default"/>
<setEntry value="org.osgi.util.position.source@default:default"/> <setEntry value="org.eclipse.jetty.server.source"/>
<setEntry value="org.osgi.util.xml@default:default"/> <setEntry value="org.eclipse.jetty.server@default:default"/>
<setEntry value="org.osgi.util.xml.source@default:default"/> <setEntry value="org.eclipse.jetty.servlet.source"/>
<setEntry value="org.eclipse.osgi.services@default:default"/> <setEntry value="org.eclipse.jetty.servlet@default:default"/>
<setEntry value="org.eclipse.osgi.services.source@default:default"/> <setEntry value="org.eclipse.jetty.util.ajax.source"/>
<setEntry value="org.eclipse.equinox.cm@default:default"/> <setEntry value="org.eclipse.jetty.util.ajax@default:default"/>
<setEntry value="com.sun.istack.commons-runtime@default:default"/> <setEntry value="org.eclipse.jetty.util.source"/>
<setEntry value="jaxb-api@default:default"/> <setEntry value="org.eclipse.jetty.util@default:default"/>
<setEntry value="com.sun.xml.bind.jaxb-impl@default:default"/> <setEntry value="org.eclipse.jetty.webapp.source"/>
<setEntry value="javax.xml.stream@default:default"/> <setEntry value="org.eclipse.jetty.webapp@default:default"/>
<setEntry value="javax.xml.ws@default:default"/> <setEntry value="org.eclipse.jetty.websocket.api.source"/>
<setEntry value="javax.xml.soap@default:default"/> <setEntry value="org.eclipse.jetty.websocket.api@default:default"/>
<setEntry value="org.eclipse.osgi.util@default:default"/> <setEntry value="org.eclipse.jetty.websocket.client.source"/>
<setEntry value="org.eclipse.osgi.util.source@default:default"/> <setEntry value="org.eclipse.jetty.websocket.client@default:default"/>
<setEntry value="com.chargebee.chargebee-java@default:default"/> <setEntry value="org.eclipse.jetty.websocket.common.source"/>
<setEntry value="com.jcraft.jsch@default:default"/> <setEntry value="org.eclipse.jetty.websocket.common@default:default"/>
<setEntry value="com.amazon.aws.aws-java-api@default:default"/> <setEntry value="org.eclipse.jetty.xml.source"/>
<setEntry value="com.amazon.aws.aws-java-api.source@default:default"/> <setEntry value="org.eclipse.jetty.xml@default:default"/>
<setEntry value="org.objectweb.asm@default:default"/> <setEntry value="org.eclipse.osgi.services.source"/>
<setEntry value="org.objectweb.asm.commons@default:default"/> <setEntry value="org.eclipse.osgi.services@default:default"/>
<setEntry value="org.objectweb.asm.analysis@default:default"/> <setEntry value="org.eclipse.osgi.source"/>
<setEntry value="org.objectweb.asm.tree@default:default"/> <setEntry value="org.eclipse.osgi.util.source"/>
<setEntry value="org.objectweb.asm.util@default:default"/> <setEntry value="org.eclipse.osgi.util@default:default"/>
<setEntry value="org.objectweb.asm.source@default:default"/> <setEntry value="org.eclipse.osgi@-1:true"/>
<setEntry value="org.objectweb.asm.analysis.source@default:default"/> <setEntry value="org.hyperic.sigar@default:default"/>
<setEntry value="org.objectweb.asm.commons.source@default:default"/> <setEntry value="org.jvnet.mimepull@default:default"/>
<setEntry value="org.objectweb.asm.tree.source@default:default"/> <setEntry value="org.mongodb.bson.source"/>
<setEntry value="org.objectweb.asm.util.source@default:default"/> <setEntry value="org.mongodb.bson@default:default"/>
<setEntry value="org.eclipse.jetty.apache-jsp@4:true"/> <setEntry value="org.mongodb.driver-core.source"/>
<setEntry value="org.eclipse.jetty.apache-jsp.source@default:default"/> <setEntry value="org.mongodb.driver-core@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot.jsp@default:default"/> <setEntry value="org.mongodb.driver-sync@default:default"/>
<setEntry value="org.eclipse.jetty.osgi.boot.jsp.source@default:default"/> <setEntry value="org.mortbay.jasper.apache-el@default:default"/>
<setEntry value="org.apache.geronimo.specs.geronimo-jta_1.1_spec@default:default"/> <setEntry value="org.mortbay.jasper.apache-jsp@default:default"/>
<setEntry value="org.apache.aries.spifly.dynamic.bundle@3:true"/> <setEntry value="org.objectweb.asm.analysis.source"/>
<setEntry value="org.apache.aries.spifly.dynamic.bundle.source@default:default"/> <setEntry value="org.objectweb.asm.analysis@default:default"/>
<setEntry value="org.mortbay.jasper.apache-el@default:default"/> <setEntry value="org.objectweb.asm.commons.source"/>
<setEntry value="org.mortbay.jasper.apache-jsp@default:default"/> <setEntry value="org.objectweb.asm.commons@default:default"/>
<setEntry value="org.eclipse.jdt.core.compiler.batch@default:default"/> <setEntry value="org.objectweb.asm.source"/>
<setEntry value="org.apache.taglibs.standard-impl@default:default"/> <setEntry value="org.objectweb.asm.tree.source"/>
<setEntry value="org.apache.taglibs.taglibs-standard-spec@default:default"/> <setEntry value="org.objectweb.asm.tree@default:default"/>
<setEntry value="javax.annotation@default:default"/> <setEntry value="org.objectweb.asm.util.source"/>
<setEntry value="org.eclipse.jetty.osgi-servlet-api@default:default"/> <setEntry value="org.objectweb.asm.util@default:default"/>
<setEntry value="org.apache.xalan@default:default"/> <setEntry value="org.objectweb.asm@default:default"/>
<setEntry value="org.apache.xml.serializer@default:default"/> <setEntry value="org.osgi.service.packageadmin@default:default"/>
<setEntry value="org.eclipse.equinox.event@default:default"/> <setEntry value="org.osgi.service.url@default:default"/>
<setEntry value="org.eclipse.jetty.annotations@4:true"/> <setEntry value="org.osgi.util.function.source"/>
<setEntry value="org.eclipse.jetty.jndi@default:default"/> <setEntry value="org.osgi.util.function@default:default"/>
<setEntry value="org.eclipse.jetty.plus@default:default"/> <setEntry value="org.osgi.util.measurement.source"/>
<setEntry value="com.sap.db.jdbc@default:default"/> <setEntry value="org.osgi.util.measurement@default:default"/>
<setEntry value="com.sap.db.jdbc.source@default:default"/> <setEntry value="org.osgi.util.position.source"/>
<setEntry value="org.osgi.service.packageadmin@default:default"/> <setEntry value="org.osgi.util.position@default:default"/>
<setEntry value="org.osgi.service.url@default:default"/> <setEntry value="org.osgi.util.promise.source"/>
<setEntry value="com.github.haifengl.smile-core@default:default"/> <setEntry value="org.osgi.util.promise@default:default"/>
<setEntry value="com.github.haifengl.smile-core.source@default:default"/> <setEntry value="org.osgi.util.xml.source"/>
<setEntry value="com.github.haifengl.smile-data@default:default"/> <setEntry value="org.osgi.util.xml@default:default"/>
<setEntry value="com.github.haifengl.smile-data.source@default:default"/> <setEntry value="org.owasp.encoder.source"/>
<setEntry value="com.github.haifengl.smile-graph@default:default"/> <setEntry value="org.owasp.encoder@default:default"/>
<setEntry value="com.github.haifengl.smile-graph.source@default:default"/> <setEntry value="routeconverter@default:default"/>
<setEntry value="com.github.haifengl.smile-math@default:default"/> <setEntry value="slf4j.api@default:default"/>
<setEntry value="com.github.haifengl.smile-math.source@default:default"/> <setEntry value="slf4j.jdk14@default:false"/>
<setEntry value="com.google.gson@default:default"/> </setAttribute>
<setEntry value="com.google.gson.source@default:default"/>
</setAttribute>
<setAttribute key="selected_workspace_bundles"> <setAttribute key="selected_workspace_bundles">
<setEntry value="com.sap.sailing.geocoding@default:default"/> <setEntry value="com.google.gwt.servlet@default:default"/>
<setEntry value="com.sap.sailing.domain.common@default:default"/> <setEntry value="com.googlecode.java-diff-utils@default:default"/>
<setEntry value="com.sap.sailing.domain@default:default"/> <setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
<setEntry value="com.sap.sailing.news@4:true"/> <setEntry value="com.sap.sailing.competitorimport@default:default"/>
<setEntry value="com.sap.sailing.domain.tractracadapter@5:true"/> <setEntry value="com.sap.sailing.dashboards.gwt@6:true"/>
<setEntry value="com.sap.sailing.expeditionconnector@default:default"/> <setEntry value="com.sap.sailing.datamining.provider@default:default"/>
<setEntry value="com.sap.sailing.domain.windfinderadapter@4:true"/> <setEntry value="com.sap.sailing.datamining.shared@default:default"/>
<setEntry value="com.sap.sailing.server@5:true"/> <setEntry value="com.sap.sailing.datamining@5:true"/>
<setEntry value="com.sap.sailing.server.gateway@5:true"/> <setEntry value="com.sap.sailing.declination@default:default"/>
<setEntry value="com.sap.sailing.server.gateway.interfaces@default:default"/> <setEntry value="com.sap.sailing.domain.bravoadapter@5:true"/>
<setEntry value="com.tractrac.clientmodule@default:default"/> <setEntry value="com.sap.sailing.domain.common@default:default"/>
<setEntry value="com.sap.sailing.declination@default:default"/> <setEntry value="com.sap.sailing.domain.deckmanadapter@5:true"/>
<setEntry value="com.sap.sailing.domain.persistence@default:default"/> <setEntry value="com.sap.sailing.domain.expeditionadapter@5:true"/>
<setEntry value="com.sap.sailing.domain.swisstimingadapter@5:true"/> <setEntry value="com.sap.sailing.domain.igtimiadapter.gateway@5:true"/>
<setEntry value="com.sap.sailing.domain.swisstimingadapter.persistence@4:true"/> <setEntry value="com.sap.sailing.domain.igtimiadapter.persistence@default:default"/>
<setEntry value="com.sap.sailing.domain.swisstimingreplayadapter@4:true"/> <setEntry value="com.sap.sailing.domain.igtimiadapter@4:true"/>
<setEntry value="com.sap.sailing.domain.tractracadapter.persistence@4:true"/> <setEntry value="com.sap.sailing.domain.oceanraceadapter@5:true"/>
<setEntry value="com.sap.sailing.gwt.ui@6:true"/> <setEntry value="com.sap.sailing.domain.persistence@default:default"/>
<setEntry value="com.sap.sailing.udpconnector@default:default"/> <setEntry value="com.sap.sailing.domain.racelogtrackingadapter@4:true"/>
<setEntry value="com.sap.sailing.simulator@default:default"/> <setEntry value="com.sap.sailing.domain.shared.android@default:default"/>
<setEntry value="com.sap.sailing.www@5:true"/> <setEntry value="com.sap.sailing.domain.swisstimingadapter.persistence@4:true"/>
<setEntry value="com.sap.sailing.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.swisstimingadapter@5:true"/>
<setEntry value="com.sap.sailing.kiworesultimport@4:true"/> <setEntry value="com.sap.sailing.domain.swisstimingreplayadapter@4:true"/>
<setEntry value="com.sap.sailing.ess40.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.tractracadapter.persistence@4:true"/>
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.tractracadapter@5:true"/>
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.windfinderadapter@4:true"/>
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.yellowbrickadapter.persistence@4:true"/>
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain.yellowbrickadapter@5:true"/>
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/> <setEntry value="com.sap.sailing.domain@default:default"/>
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/> <setEntry value="com.sap.sailing.ess40.resultimport@4:true"/>
<setEntry value="com.sap.sailing.velum.resultimport@4:true"/> <setEntry value="com.sap.sailing.expeditionconnector.common@default:default"/>
<setEntry value="com.sap.sailing.monitoring@7:true"/> <setEntry value="com.sap.sailing.expeditionconnector.persistence@4:true"/>
<setEntry value="com.sap.sailing.xrr.resultimport@4:true"/> <setEntry value="com.sap.sailing.expeditionconnector@default:default"/>
<setEntry value="com.sap.sailing.domain.igtimiadapter@4:true"/> <setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
<setEntry value="com.sap.sailing.domain.igtimiadapter.persistence@default:default"/> <setEntry value="com.sap.sailing.geocoding@default:default"/>
<setEntry value="com.sap.sailing.domain.racelogtrackingadapter@4:true"/> <setEntry value="com.sap.sailing.grib@default:default"/>
<setEntry value="com.sap.sailing.domain.deckmanadapter@5:true"/> <setEntry value="com.sap.sailing.gwt.ui@6:true"/>
<setEntry value="com.sap.sailing.domain.oceanraceadapter@5:true"/> <setEntry value="com.sap.sailing.hanaexport@5:true"/>
<setEntry value="com.sap.sailing.domain.yellowbrickadapter@5:true"/> <setEntry value="com.sap.sailing.kiworesultimport@4:true"/>
<setEntry value="com.sap.sailing.domain.yellowbrickadapter.persistence@4:true"/> <setEntry value="com.sap.sailing.landscape.common@default:default"/>
<setEntry value="com.sap.sailing.xrr.structureimport@default:default"/> <setEntry value="com.sap.sailing.landscape.gateway@5:true"/>
<setEntry value="com.sap.sailing.server.gateway.serialization.shared.android@default:default"/> <setEntry value="com.sap.sailing.landscape.ui@default:default"/>
<setEntry value="com.sap.sailing.server.gateway.serialization@default:default"/> <setEntry value="com.sap.sailing.landscape@default:default"/>
<setEntry value="com.sap.sailing.dashboards.gwt@6:true"/> <setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
<setEntry value="com.sap.sailing.dashboards.gwt@6:true"/> <setEntry value="com.sap.sailing.manage2sail@default:default"/>
<setEntry value="com.sap.sailing.datamining@5:true"/> <setEntry value="com.sap.sailing.monitoring@7:true"/>
<setEntry value="com.sap.sailing.datamining.shared@default:default"/> <setEntry value="com.sap.sailing.news@4:true"/>
<setEntry value="com.sap.sailing.polars@5:true"/> <setEntry value="com.sap.sailing.nmeaconnector@default:default"/>
<setEntry value="com.sap.sailing.windestimation@5:true"/> <setEntry value="com.sap.sailing.polars.datamining.shared@default:default"/>
<setEntry value="com.sap.sailing.polars.datamining@5:true"/> <setEntry value="com.sap.sailing.polars.datamining@5:true"/>
<setEntry value="com.sap.sailing.domain.shared.android@default:default"/> <setEntry value="com.sap.sailing.polars@5:true"/>
<setEntry value="com.sap.sailing.manage2sail@default:default"/> <setEntry value="com.sap.sailing.resultimport@4:true"/>
<setEntry value="com.sap.sailing.polars.datamining.shared@default:default"/> <setEntry value="com.sap.sailing.routeconverterjava11extension@default:false"/>
<setEntry value="com.sap.sailing.xrr.schema@default:default"/> <setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
<setEntry value="com.sap.sailing.server.trackfiles@default:default"/> <setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
<setEntry value="com.sap.sailing.competitorimport@default:default"/> <setEntry value="com.sap.sailing.server.gateway.interfaces@default:default"/>
<setEntry value="com.sap.sailing.datamining.provider@default:default"/> <setEntry value="com.sap.sailing.server.gateway.serialization.shared.android@default:default"/>
<setEntry value="com.sap.sailing.grib@default:default"/> <setEntry value="com.sap.sailing.server.gateway.serialization@default:default"/>
<setEntry value="com.sap.sailing.nmeaconnector@default:default"/> <setEntry value="com.sap.sailing.server.gateway.test.support@5:true"/>
<setEntry value="com.sap.sailing.domain.expeditionadapter@5:true"/> <setEntry value="com.sap.sailing.server.gateway@5:true"/>
<setEntry value="com.sap.sailing.expeditionconnector.persistence@4:true"/> <setEntry value="com.sap.sailing.server.interface@default:default"/>
<setEntry value="com.sap.sailing.expeditionconnector.common@default:default"/> <setEntry value="com.sap.sailing.server.trackfiles@default:default"/>
<setEntry value="com.sap.sailing.domain.bravoadapter@5:true"/> <setEntry value="com.sap.sailing.server@5:true"/>
<setEntry value="net.sf.marineapi@default:default"/> <setEntry value="com.sap.sailing.shared.persistence@default:default"/>
<setEntry value="com.sap.sailing.routeconverterjava11extension@default:default"/> <setEntry value="com.sap.sailing.shared.server.gateway@5:true"/>
<setEntry value="com.sap.sailing.server.interface@default:default"/> <setEntry value="com.sap.sailing.shared.server@5:true"/>
<setEntry value="com.sap.sse.datamining.ui@default:default"/> <setEntry value="com.sap.sailing.simulator@default:default"/>
<setEntry value="com.sap.sailing.domain.igtimiadapter.gateway@5:true"/> <setEntry value="com.sap.sailing.udpconnector@default:default"/>
<setEntry value="com.sap.sailing.shared.server@5:true"/> <setEntry value="com.sap.sailing.velum.resultimport@4:true"/>
<setEntry value="com.sap.sailing.shared.server.gateway@5:true"/> <setEntry value="com.sap.sailing.windestimation@5:true"/>
<setEntry value="com.sap.sailing.shared.persistence@default:default"/> <setEntry value="com.sap.sailing.www@5:true"/>
<setEntry value="com.sap.sailing.landscape@default:default"/> <setEntry value="com.sap.sailing.xrr.resultimport@4:true"/>
<setEntry value="com.sap.sailing.landscape.gateway@5:true"/> <setEntry value="com.sap.sailing.xrr.schema@default:default"/>
<setEntry value="com.sap.sailing.landscape.common@default:default"/> <setEntry value="com.sap.sailing.xrr.structureimport@default:default"/>
<setEntry value="com.sap.sailing.landscape.ui@default:default"/> <setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
<setEntry value="com.sap.sailing.hanaexport@5:true"/> <setEntry value="com.sap.sse.common@default:default"/>
<setEntry value="com.tractrac.clientmodule@default:default"/> <setEntry value="com.sap.sse.datamining.annotations@default:default"/>
<setEntry value="com.sap.sse.gwt@default:default"/> <setEntry value="com.sap.sse.datamining.shared@default:default"/>
<setEntry value="com.google.gwt.servlet@default:default"/> <setEntry value="com.sap.sse.datamining.ui@default:default"/>
<setEntry value="com.sap.sse.security@default:default"/> <setEntry value="com.sap.sse.datamining@default:default"/>
<setEntry value="com.sap.sse.security.ui@6:true"/> <setEntry value="com.sap.sse.debranding@default:default"/>
<setEntry value="com.sap.sse.security.userstore.mongodb@4:true"/> <setEntry value="com.sap.sse.filestorage@4:true"/>
<setEntry value="com.sap.sse@default:default"/> <setEntry value="com.sap.sse.gwt.adminconsole@default:default"/>
<setEntry value="com.sap.sse.common@default:default"/> <setEntry value="com.sap.sse.gwt@default:default"/>
<setEntry value="com.sap.sse.datamining@default:default"/> <setEntry value="com.sap.sse.landscape.aws.common@default:default"/>
<setEntry value="com.sap.sse.datamining.annotations@default:default"/> <setEntry value="com.sap.sse.landscape.aws.persistence@default:default"/>
<setEntry value="com.sap.sse.datamining.shared@default:default"/> <setEntry value="com.sap.sse.landscape.aws@4:true"/>
<setEntry value="com.sap.sse.gwt.adminconsole@default:default"/> <setEntry value="com.sap.sse.landscape.common@default:default"/>
<setEntry value="com.sap.sse.mongodb@default:default"/> <setEntry value="com.sap.sse.landscape@default:default"/>
<setEntry value="com.sap.sse.operationaltransformation@default:default"/> <setEntry value="com.sap.sse.mail@5:true"/>
<setEntry value="com.sap.sse.replication@6:true"/> <setEntry value="com.sap.sse.mongodb@default:default"/>
<setEntry value="com.sap.sse.filestorage@4:true"/> <setEntry value="com.sap.sse.operationaltransformation@default:default"/>
<setEntry value="com.sap.sse.shared.android@default:default"/> <setEntry value="com.sap.sse.replication.interfaces@default:default"/>
<setEntry value="com.sap.sse.mail@5:true"/> <setEntry value="com.sap.sse.replication.persistence@default:default"/>
<setEntry value="com.sap.sse.threadmanager@default:default"/> <setEntry value="com.sap.sse.replication@6:true"/>
<setEntry value="com.sap.sse.security.common@default:default"/> <setEntry value="com.sap.sse.security.common@default:default"/>
<setEntry value="org.json.simple@default:default"/> <setEntry value="com.sap.sse.security.interface@default:default"/>
<setEntry value="org.moxieapps.gwt.highcharts@default:default"/> <setEntry value="com.sap.sse.security.persistence@default:default"/>
<setEntry value="com.googlecode.java-diff-utils@default:default"/> <setEntry value="com.sap.sse.security.ui@6:true"/>
<setEntry value="org.mp4parser.isoparser@default:default"/> <setEntry value="com.sap.sse.security.userstore.mongodb@4:true"/>
<setEntry value="com.sap.sse.replication.interfaces@default:default"/> <setEntry value="com.sap.sse.security@default:default"/>
<setEntry value="com.sap.sse.security.persistence@default:default"/> <setEntry value="com.sap.sse.shared.android@default:default"/>
<setEntry value="com.sap.sse.security.interface@default:default"/> <setEntry value="com.sap.sse.threadmanager@default:default"/>
<setEntry value="com.sap.sse.replication.persistence@default:default"/> <setEntry value="com.sap.sse@default:default"/>
<setEntry value="com.sap.sse.landscape.common@default:default"/> <setEntry value="com.tractrac.clientmodule@default:default"/>
<setEntry value="com.sap.sse.landscape@default:default"/> <setEntry value="elemental2@default:default"/>
<setEntry value="com.sap.sse.landscape.aws@4:true"/> <setEntry value="net.sf.marineapi@default:default"/>
<setEntry value="com.sap.sse.landscape.aws.common@default:default"/> <setEntry value="org.json.simple@default:default"/>
<setEntry value="com.sap.sse.landscape.aws.persistence@default:default"/> <setEntry value="org.moxieapps.gwt.highcharts@default:default"/>
<setEntry value="com.sap.sse.debranding@default:default"/> <setEntry value="org.mp4parser.isoparser@default:default"/>
<setEntry value="elemental2@default:default"/> </setAttribute>
<setEntry value="com.sap.sailing.server.gateway.test.support@5:true"/>
</setAttribute>
<booleanAttribute key="show_selected_only" value="false"/> <booleanAttribute key="show_selected_only" value="false"/>
<booleanAttribute key="tracing" value="false"/> <booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/> <booleanAttribute key="useCustomFeatures" value="false"/>
@@ -5209,7 +5209,9 @@ Replicator {
// try to obtain an error message from the connection's error stream: // try to obtain an error message from the connection's error stream:
try { try {
message = new BufferedReader( message = new BufferedReader(
new InputStreamReader(((HttpURLConnection) connection).getErrorStream())).readLine(); new InputStreamReader(((HttpURLConnection) connection).getErrorStream(),
HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8")))
.readLine();
} catch (Exception exceptionTryingToReadErrorStream) { } catch (Exception exceptionTryingToReadErrorStream) {
// in this case we just stay with the exception's message // in this case we just stay with the exception's message
} }
@@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -53,7 +54,7 @@ public enum ConfigurationManager {
this.status = ReadingConfigurationFileStatus.ERROR_FINDING_CONFIG_FILE; this.status = ReadingConfigurationFileStatus.ERROR_FINDING_CONFIG_FILE;
this.errorMessage = "Invalid configuration file path ( " + configFileLocation + ")! Using default configuration values!"; this.errorMessage = "Invalid configuration file path ( " + configFileLocation + ")! Using default configuration values!";
} }
final InputStreamReader reader = new InputStreamReader(inputStream); final InputStreamReader reader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
final BufferedReader buffer = new BufferedReader(reader); final BufferedReader buffer = new BufferedReader(reader);
String line = null; String line = null;
String[] elements = null; String[] elements = null;
@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -25,7 +26,7 @@ public class PolarDiagramCSV extends PolarDiagramBase {
public PolarDiagramCSV(String inputFile) throws IOException { public PolarDiagramCSV(String inputFile) throws IOException {
ClassLoader cl = this.getClass().getClassLoader(); ClassLoader cl = this.getClass().getClassLoader();
InputStream csvFile = cl.getResourceAsStream(inputFile); InputStream csvFile = cl.getResourceAsStream(inputFile);
InputStreamReader isr = new InputStreamReader(csvFile); InputStreamReader isr = new InputStreamReader(csvFile, Charset.forName("UTF-8"));
BufferedReader bfr = new BufferedReader(isr); BufferedReader bfr = new BufferedReader(isr);
List<Speed> windSpeeds = new ArrayList<Speed>(); List<Speed> windSpeeds = new ArrayList<Speed>();
@@ -10,14 +10,15 @@ Import-Package: com.sap.sailing.domain.common,
com.sap.sailing.domain.leaderboard, com.sap.sailing.domain.leaderboard,
com.sap.sailing.domain.persistence, com.sap.sailing.domain.persistence,
com.sap.sailing.xrr.schema, com.sap.sailing.xrr.schema,
org.mockito;version="4.8.1",
org.mockito.stubbing;version="4.8.1",
org.osgi.framework;version="1.5.0" org.osgi.framework;version="1.5.0"
Fragment-Host: com.sap.sailing.yachtscoring.resultimport Fragment-Host: com.sap.sailing.yachtscoring.resultimport
Require-Bundle: org.junit;bundle-version="4.8.2", Require-Bundle: org.junit;bundle-version="4.8.2",
com.sap.sse.common, com.sap.sse.common,
org.mockito.mockito-core;bundle-version="1.9.5",
org.objenesis;bundle-version="1.3.0",
org.hamcrest;bundle-version="2.2.0", org.hamcrest;bundle-version="2.2.0",
com.sap.sse, com.sap.sse,
com.sap.sailing.server, com.sap.sailing.server,
com.sap.sailing.server.interface, com.sap.sailing.server.interface,
com.sap.sse.replication.interfaces com.sap.sse.replication.interfaces,
org.objenesis;bundle-version="3.3.0"
@@ -22,7 +22,6 @@ import com.sap.sailing.yachtscoring.resultimport.YachtScoringCompetitorProvider;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
public class CompetitorImportTest extends AbstractCharlstonRaceWeek2015Test { public class CompetitorImportTest extends AbstractCharlstonRaceWeek2015Test {
@Test @Test
public void simpleCompetitorImportTest() throws FileNotFoundException, IOException, JAXBException { public void simpleCompetitorImportTest() throws FileNotFoundException, IOException, JAXBException {
ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class); ResultUrlRegistry resultUrlRegistry = mock(ResultUrlRegistry.class);
@@ -13,6 +13,7 @@ import java.util.logging.Level;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
@@ -258,8 +259,10 @@ implements ApplicationProcess<ShardingKey, MetricsT, ProcessT> {
final HttpPost postRequest = new HttpPost(url.toString()); final HttpPost postRequest = new HttpPost(url.toString());
final HttpClient client = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategyForAllRedirectResponseCodes()).build(); final HttpClient client = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategyForAllRedirectResponseCodes()).build();
final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final ByteArrayOutputStream bos = new ByteArrayOutputStream();
client.execute(postRequest).getEntity().writeTo(bos); final HttpEntity entity = client.execute(postRequest).getEntity();
return (JSONObject) new JSONParser().parse(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray()))); entity.writeTo(bos);
return (JSONObject) new JSONParser().parse(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray()),
HttpUrlConnectionHelper.getCharsetFromHttpEntity(entity, "UTF-8")));
} }
@Override @Override
@@ -58,7 +58,8 @@ public interface OperationsToMasterSender<S, O extends OperationWithResult<S, ?>
final int responseCode = connection.getResponseCode(); final int responseCode = connection.getResponseCode();
if (responseCode < 300 || responseCode >= 500 || responseCode == 404) { if (responseCode < 300 || responseCode >= 500 || responseCode == 404) {
// if OK or an internal error, process as usual; in case of >= 500 this will throw an exception // if OK or an internal error, process as usual; in case of >= 500 this will throw an exception
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(),
HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(connection, "UTF-8")));
bufferedReader.close(); bufferedReader.close();
} else { } else {
logger.warning( logger.warning(
@@ -711,7 +711,7 @@ public class ReplicationServiceImpl implements ReplicationService, OperationsToM
final URLConnection initialLoadConnection = HttpUrlConnectionHelper final URLConnection initialLoadConnection = HttpUrlConnectionHelper
.redirectConnectionWithBearerToken(initialLoadURL, /* HTTP request method */ "POST", master.getBearerToken()); .redirectConnectionWithBearerToken(initialLoadURL, /* HTTP request method */ "POST", master.getBearerToken());
final InputStream is = (InputStream) initialLoadConnection.getContent(); final InputStream is = (InputStream) initialLoadConnection.getContent();
final InputStreamReader queueNameReader = new InputStreamReader(is); final InputStreamReader queueNameReader = new InputStreamReader(is, HttpUrlConnectionHelper.getCharsetFromConnectionOrDefault(initialLoadConnection, "UTF-8"));
final String queueName = new BufferedReader(queueNameReader).readLine(); final String queueName = new BufferedReader(queueNameReader).readLine();
queueNameReader.close(); queueNameReader.close();
final Channel channel = master.createChannel(); final Channel channel = master.createChannel();
@@ -42,6 +42,7 @@ import com.sap.sse.security.shared.HasPermissions;
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier; import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
import com.sap.sse.security.shared.WildcardPermission; import com.sap.sse.security.shared.WildcardPermission;
import com.sap.sse.security.util.SecuredServer; import com.sap.sse.security.util.SecuredServer;
import com.sap.sse.util.HttpUrlConnectionHelper;
import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes; import com.sap.sse.util.LaxRedirectStrategyForAllRedirectResponseCodes;
public class SecuredServerImpl implements SecuredServer { public class SecuredServerImpl implements SecuredServer {
@@ -80,7 +81,8 @@ public class SecuredServerImpl implements SecuredServer {
response.getEntity().writeTo(bos); response.getEntity().writeTo(bos);
try { try {
jsonParseResult = new JSONParser() jsonParseResult = new JSONParser()
.parse(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray()))); .parse(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray()),
HttpUrlConnectionHelper.getCharsetFromHttpEntity(response.getEntity(), "UTF-8")));
} catch (ParseException e) { } catch (ParseException e) {
jsonParseResult = new String(bos.toByteArray()); jsonParseResult = new String(bos.toByteArray());
} }
@@ -7,7 +7,9 @@ import java.util.EnumMap;
import org.junit.Test; import org.junit.Test;
public class EnumSetSerializationTest { import com.sap.sse.common.SortingOrder;
public class EnumMapSerializationTest {
private static enum MyBoolean { private static enum MyBoolean {
TRUE, FALSE TRUE, FALSE
}; };
@@ -25,4 +27,10 @@ public class EnumSetSerializationTest {
enumMap.put(MyBoolean.FALSE, 0); enumMap.put(MyBoolean.FALSE, 0);
assertSame(MyBoolean.class, com.sap.sse.util.EnumMapUtil.getKeyType(enumMap)); assertSame(MyBoolean.class, com.sap.sse.util.EnumMapUtil.getKeyType(enumMap));
} }
@Test
public void testEmptyEnumMapWithSortingOrderKeys() throws IOException, ClassNotFoundException {
final EnumMap<SortingOrder, Integer> myEnumMap = new EnumMap<>(SortingOrder.class);
assertSame(SortingOrder.class, com.sap.sse.util.EnumMapUtil.getKeyType(myEnumMap));
}
} }
@@ -1,131 +0,0 @@
package com.sap.sse.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;
public class ThreadPoolWithThreadLocalsTest {
private static final Logger logger = Logger.getLogger(ThreadPoolWithThreadLocalsTest.class.getName());
private static Field threadLocalsField;
private static Field inheritableThreadLocalsField;
static {
try {
threadLocalsField = Thread.class.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
} catch (NoSuchFieldException | SecurityException e) {
logger.log(Level.SEVERE, "Problem finding field threadLocals", e);
}
try {
inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals");
inheritableThreadLocalsField.setAccessible(true);
} catch (NoSuchFieldException | SecurityException e) {
logger.log(Level.SEVERE, "Problem finding field inheritableThreadLocals", e);
}
}
@Test(expected = ThreadLocalCollisionException.class)
public void testThreadReuseWithThreadLocalUsingFixedThreadPool() throws Exception {
testThreadReuseWithThreadLocal(() -> Executors.newFixedThreadPool(2));
}
@Test(expected = ThreadLocalCollisionException.class)
public void testThreadReuseWithInheritableThreadLocalUsingFixedThreadPool() throws Exception {
testThreadReuseWithInheritableThreadLocal(() -> Executors.newFixedThreadPool(2));
}
private void testThreadReuseWithThreadLocal(final Supplier<ExecutorService> executorFactory) throws Exception {
final ExecutorService executor = executorFactory.get();
final Thread thread1 = executor.submit(() -> {
ThreadLocal<String> tl = new ThreadLocal<>();
tl.set("top secret");
assertTrue(containsThreadLocalWithValue(Thread.currentThread(), "top secret", threadLocalsField));
return Thread.currentThread();
}).get();
Thread thread2 = null;
while (thread1 != thread2) {
thread2 = executor.submit(() -> Thread.currentThread()).get();
}
assertSame(thread1, thread2);
if (containsThreadLocalWithValue(thread2, "top secret", threadLocalsField)) {
throw new ThreadLocalCollisionException(
"Reused Thread contains some old top secret value from ThreadLocal!");
}
}
private void testThreadReuseWithInheritableThreadLocal(final Supplier<ExecutorService> executorFactory)
throws Exception {
final ExecutorService executor = executorFactory.get();
final InheritableThreadLocal<String> itl = new InheritableThreadLocal<>();
itl.set("top secret");
final Thread thread1 = executor.submit(() -> {
logger.info("" +
containsThreadLocalWithValue(Thread.currentThread(), "top secret", inheritableThreadLocalsField));
return Thread.currentThread();
}).get();
assertEquals("top secret", itl.get());
itl.remove();
Thread thread2 = null;
while (thread1 != thread2) {
thread2 = executor.submit(() -> Thread.currentThread()).get();
}
assertEquals(thread1, thread2);
if (containsThreadLocalWithValue(thread2, "top secret", inheritableThreadLocalsField)) {
throw new ThreadLocalCollisionException(
"Reused Thread contains some old top secret value from InheritableThreadLocal!");
}
}
private boolean containsThreadLocalWithValue(final Thread thread, final String value, final Field threadLocalsField)
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
Object threadLocals = threadLocalsField.get(thread);
if (threadLocals != null) {
final Field tableField = threadLocals.getClass().getDeclaredField("table");
tableField.setAccessible(true);
final Object[] table = (Object[]) tableField.get(threadLocals);
for (int j = 0; j < table.length; j++) {
final WeakReference<?> entry = (WeakReference<?>) table[j];
if (entry != null) {
@SuppressWarnings("unchecked")
final ThreadLocal<Object> key = (ThreadLocal<Object>) entry.get();
if (key != null) {
final Field valueField = entry.getClass().getDeclaredField("value");
valueField.setAccessible(true);
final Object entryvalue = valueField.get(entry);
if (value.equals(entryvalue)) {
logger.info(threadLocalsField.getName() + ": found thread local value \"" + value
+ "\" in thread " + thread.getId());
return true;
}
}
}
}
logger.info("NOT found thread local value " + value + " in thread " + thread.getId());
return false;
} else {
logger.info("NOT found any thread local in thread " + thread.getId());
return false;
}
}
private static class ThreadLocalCollisionException extends Exception {
private static final long serialVersionUID = 5413856555774135094L;
ThreadLocalCollisionException(String msg) {
super(msg);
}
}
}
+1
View File
@@ -32,6 +32,7 @@ Require-Bundle: com.sap.sse.common,
Import-Package: javax.servlet;version="3.1.0", Import-Package: javax.servlet;version="3.1.0",
javax.servlet.http;version="3.1.0", javax.servlet.http;version="3.1.0",
javax.ws.rs.core;version="1.1.1", javax.ws.rs.core;version="1.1.1",
org.apache.commons.fileupload;version="1.2.2",
org.osgi.framework;version="1.8.0", org.osgi.framework;version="1.8.0",
org.osgi.util.tracker;version="1.5.1" org.osgi.util.tracker;version="1.5.1"
Automatic-Module-Name: com.sap.sse Automatic-Module-Name: com.sap.sse
@@ -50,11 +50,15 @@ public class EnumMapUtil {
@Override @Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
final Class<?> result; Class<?> result = null;
if (desc.getName().equals("java.util.EnumMap")) { if (desc.getName().equals("java.util.EnumMap")) {
result = com.sap.sse.util.EnumMap.class; result = EnumMap.class;
} else { } else {
result = super.resolveClass(desc); try {
result = super.resolveClass(desc);
} catch (ClassNotFoundException e) {
result = Class.forName(desc.getName(), false, Thread.currentThread().getContextClassLoader());
}
} }
return result; return result;
} }
@@ -0,0 +1,44 @@
package com.sap.sse.util;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import org.apache.commons.fileupload.FileItem;
import org.apache.http.ParseException;
import org.apache.http.entity.ContentType;
public class FileItemHelper {
/**
* Determines the {@link Charset} for a {@link FileItem}. It does so by looking at the
* {@link FileItem}'s {@link FileItem#getContentType() content type}, submitting it to
* the {@link ContentType#parse(String)} method if not {@code null}. If {@code null}
* or if the {@link ContentType#parse(String)} method throws an exception, the
* {@link Charset#defaultCharset() default charset} is returned. Otherwise, the
* charset is {@link ContentType#getCharset() fetched from the content type}.
*/
public static Charset getCharset(FileItem fileItem) {
return getCharset(fileItem, Charset.defaultCharset());
}
/**
* Determines the {@link Charset} for a {@link FileItem}. It does so by looking at the {@link FileItem}'s
* {@link FileItem#getContentType() content type}, submitting it to the {@link ContentType#parse(String)} method if
* not {@code null}. If {@code null} or if the {@link ContentType#parse(String)} method throws an exception, the
* {@code defaultCharset} is returned. Otherwise, the charset is {@link ContentType#getCharset() fetched from the
* content type}.
*/
public static Charset getCharset(FileItem fileItem, final Charset defaultCharset) {
Charset result;
try {
final ContentType contentType = fileItem.getContentType() == null ? null : ContentType.parse(fileItem.getContentType());
if (contentType != null && contentType.getCharset() != null) {
result = contentType.getCharset();
} else {
result = defaultCharset;
}
} catch (ParseException | UnsupportedCharsetException e) {
result = defaultCharset;
}
return result;
}
}
@@ -6,9 +6,14 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import com.sap.sse.common.Duration; import com.sap.sse.common.Duration;
public class HttpUrlConnectionHelper { public class HttpUrlConnectionHelper {
@@ -164,4 +169,21 @@ public class HttpUrlConnectionHelper {
return redirectConnection(url, Duration.ONE_MINUTE.times(10), optionalRequestMethod, /* pre-connect modifier */ null, return redirectConnection(url, Duration.ONE_MINUTE.times(10), optionalRequestMethod, /* pre-connect modifier */ null,
/* post-connect modifier */ null, /* optional output stream consumer */ Optional.empty()); /* post-connect modifier */ null, /* optional output stream consumer */ Optional.empty());
} }
public static Charset getCharsetFromConnectionOrDefault(URLConnection connection, String defaultCharsetName) {
Charset cs;
try {
final Charset charsetFromConnection = org.apache.http.entity.ContentType.parse(connection.getContentType()).getCharset();
cs = charsetFromConnection == null ? Charset.forName(defaultCharsetName) : charsetFromConnection;
} catch (org.apache.http.ParseException | UnsupportedCharsetException e) {
cs = Charset.forName(defaultCharsetName);
}
return cs;
}
public static Charset getCharsetFromHttpEntity(HttpEntity entity, String defaultCharsetName) {
final ContentType contentType = ContentType.getOrDefault(entity);
final Charset charsetFromContentType = contentType.getCharset();
return charsetFromContentType == null ? Charset.forName(defaultCharsetName) : charsetFromContentType;
}
} }
+2 -2
View File
@@ -175,8 +175,8 @@
<module>com.tractrac.clientmodule</module> <module>com.tractrac.clientmodule</module>
<module>com.googlecode.java-diff-utils</module> <module>com.googlecode.java-diff-utils</module>
<module>com.googlecode.mgwt</module> <module>com.googlecode.mgwt</module>
<module>net.sf.marineapi</module> <module>net.sf.marineapi</module>
<module>net.sf.marineapi.test</module> <module>net.sf.marineapi.test</module>
<module>com.sap.sailing.dashboards.gwt</module> <module>com.sap.sailing.dashboards.gwt</module>
<module>com.sap.sailing.feature</module> <module>com.sap.sailing.feature</module>
<module>org.moxieapps.gwt.highcharts</module> <module>org.moxieapps.gwt.highcharts</module>
@@ -5,6 +5,7 @@
<uses-sdk /> <uses-sdk />
<!-- <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> --> <!-- <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
@@ -35,6 +36,7 @@
<activity <activity
android:name=".ui.activities.StartActivity" android:name=".ui.activities.StartActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:exported="true"
android:launchMode="singleTask"> android:launchMode="singleTask">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -70,8 +72,7 @@
<activity <activity
android:name=".ui.activities.RegattaActivity" android:name=".ui.activities.RegattaActivity"
android:configChanges="layoutDirection|screenSize|orientation"/> android:configChanges="layoutDirection|screenSize|orientation"/>
<activity <activity android:name=".ui.activities.PositioningActivity" />
android:name=".ui.activities.PositioningActivity"/>
<activity <activity
android:name=".ui.activities.SettingActivity" android:name=".ui.activities.SettingActivity"
android:configChanges="layoutDirection|screenSize|orientation"/> android:configChanges="layoutDirection|screenSize|orientation"/>

Some files were not shown because too many files have changed in this diff Show More