Merge remote-tracking branch 'origin/master' into bug5029

This commit is contained in:
Tim Hessenmüller committed 2019-05-23 10:21:55 +02:00
commit 151db6d52e
42 files changed
+1021 -609

No files matched your search

-3
View File
@@ -36,9 +36,6 @@ installPlugins http://p2.sapsailing.com/p2/sdbg com.github.sdbg.feature.feature.
echo "Installing EasyShell..."
installPlugins http://anb0s.github.io/EasyShell de.anbos.eclipse.easyshell.feature.feature.group
echo "Installing BIRT charts (requirement for MAT)..."
installPlugins https://download.eclipse.org/birt/update-site/photon-interim/ org.eclipse.birt.chart.feature.group
echo "Installing Memory Analyzer..."
installPlugins http://download.eclipse.org/releases/2019-03 org.eclipse.mat.feature.feature.group,org.eclipse.mat.chart.feature.feature.group
@@ -143,7 +143,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
private static Logger logger = Logger.getLogger(MongoObjectFactoryImpl.class.getName());
private final MongoDatabase database;
private final CompetitorWithBoatRefJsonSerializer competitorWithBoatRefSerializer = CompetitorWithBoatRefJsonSerializer.create();
private final CompetitorJsonSerializer competitorSerializer = CompetitorJsonSerializer.create();
private final CompetitorJsonSerializer competitorSerializer = CompetitorJsonSerializer.create(/* serialize boat */ true, /* serializeNonPublicCompetitorFields */ true);
private final BoatJsonSerializer boatSerializer = BoatJsonSerializer.create();
private final TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceIdentifierServiceFinder;
private final TypeBasedServiceFinder<RaceTrackingConnectivityParametersHandler> raceTrackingConnectivityParamsServiceFinder;
@@ -159,6 +159,12 @@ public class NoAddingRaceLogWrapper implements RaceLog {
return innerRaceLog.getRawFixesIterator(startingAt, inclusive);
}
@Override
public Iterator<RaceLogEvent> getRawFixesIterator(TimePoint startingAt, boolean startingAtInclusive,
TimePoint endingAt, boolean endingAtInclusive) {
return innerRaceLog.getRawFixesIterator(startingAt, startingAtInclusive, endingAt, endingAtInclusive);
}
@Override
public Serializable getId() {
return innerRaceLog;
@@ -49,7 +49,8 @@ public class RegattaLogDeviceMappingFinder<ItemT extends WithID>
protected DeviceMappingWithRegattaLogEvent<ItemT> createMapping(DeviceIdentifier device, ItemT item,
TimePoint from, TimePoint toInclusive, Serializable originalEventId, RegattaLogDeviceMappingEvent<ItemT> event) {
return new DeviceMappingWithRegattaLogEventImpl<ItemT>(item, device, new TimeRangeImpl(from, toInclusive, /* inclusive */ true),
return new DeviceMappingWithRegattaLogEventImpl<ItemT>(item, device, new TimeRangeImpl(from,
toInclusive != null && toInclusive.before(from) ? from : toInclusive, /* inclusive */ true),
Collections.singletonList(originalEventId), event);
}
@@ -201,6 +201,17 @@ public interface Track<FixType extends Timed> extends Serializable {
*/
Iterator<FixType> getRawFixesIterator(TimePoint startingAt, boolean inclusive);
/**
* Returns an iterator starting at the first raw fix after <code>startingAt</code> (or "at or after" in case
* <code>startingAtInclusive</code> is <code>true</code>) and ending at the <code>endingAt</code> time point or just before
* in case <code>endingAtIncluive</code> is false. The fixes returned by the iterator are the raw fixes (see also
* {@link #getRawFixes()}, without any smoothening or dampening applied.
*
* Callers must have called {@link #lockForRead()} before calling this method. This will be checked, and an exception
* will be thrown in case the caller has failed to do so.
*/
Iterator<FixType> getRawFixesIterator(TimePoint startingAt, boolean startingAtInclusive, TimePoint endingAt, boolean endingAtInclusive);
/**
* Returns a descending iterator starting at the first fix before <code>startingAt</code> (or "at or before" in case
* <code>inclusive</code> is <code>true</code>). The fixes returned by the iterator are the smoothened fixes (see
@@ -335,25 +335,14 @@ public class TrackImpl<FixType extends Timed> implements Track<FixType> {
@Override
public Iterator<FixType> getFixesIterator(TimePoint startingAt, boolean inclusive) {
assertReadLock();
Iterator<FixType> result = (Iterator<FixType>) getInternalFixes().tailSet(
getDummyFix(startingAt), inclusive).iterator();
return result;
return getTimeConstrainedFixesIterator(getInternalFixes(), startingAt, inclusive, /* endingAt */ null, /* endingAtInclusive */ false);
}
@Override
public Iterator<FixType> getFixesIterator(TimePoint startingAt, boolean startingAtInclusive, TimePoint endingAt,
boolean endingAtInclusive) {
assertReadLock();
NavigableSet<FixType> set = getInternalFixes();
if (startingAt != null && endingAt != null) {
set = set.subSet(getDummyFix(startingAt), startingAtInclusive, getDummyFix(endingAt), endingAtInclusive);
} else if (endingAt != null) {
set = set.headSet(getDummyFix(endingAt), endingAtInclusive);
} else if (startingAt != null) {
set = set.tailSet(getDummyFix(startingAt), startingAtInclusive);
}
Iterator<FixType> result = set.iterator();
return result;
return getTimeConstrainedFixesIterator(getInternalFixes(), startingAt, startingAtInclusive, endingAt, endingAtInclusive);
}
@Override
@@ -380,10 +369,29 @@ public class TrackImpl<FixType extends Timed> implements Track<FixType> {
@Override
public Iterator<FixType> getRawFixesIterator(TimePoint startingAt, boolean inclusive) {
assertReadLock();
Iterator<FixType> result = (Iterator<FixType>) getInternalRawFixes().tailSet(
getDummyFix(startingAt), inclusive).iterator();
return getTimeConstrainedFixesIterator(getInternalRawFixes(), startingAt, inclusive, /* endingAt */ null, /* endingAtInclusive */ false);
}
private Iterator<FixType> getTimeConstrainedFixesIterator(NavigableSet<FixType> set, TimePoint startingAt, boolean startingAtInclusive,
TimePoint endingAt, boolean endingAtInclusive) {
assertReadLock();
if (startingAt != null && endingAt != null) {
set = set.subSet(getDummyFix(startingAt), startingAtInclusive, getDummyFix(endingAt), endingAtInclusive);
} else if (endingAt != null) {
set = set.headSet(getDummyFix(endingAt), endingAtInclusive);
} else if (startingAt != null) {
set = set.tailSet(getDummyFix(startingAt), startingAtInclusive);
}
Iterator<FixType> result = set.iterator();
return result;
}
@Override
public Iterator<FixType> getRawFixesIterator(TimePoint startingAt, boolean startingAtInclusive,
TimePoint endingAt, boolean endingAtInclusive) {
assertReadLock();
return getTimeConstrainedFixesIterator(getInternalRawFixes(), startingAt, startingAtInclusive, endingAt, endingAtInclusive);
}
@Override
public Iterator<FixType> getRawFixesDescendingIterator(TimePoint startingAt, boolean inclusive) {
@@ -19,26 +19,26 @@ public class MostProbableCandidatesInSmallTimeRangeFilterTest extends AbstractCa
@Test
public void testGetTimeWiseContiguousDistanceCandidates() {
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousDistanceCandidates(competitorCandidates, c3, /* includeStartFrom */ true);
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousCandidates(competitorCandidates, c3, /* includeStartFrom */ true);
assertContainsExactly(result, c1, c2, c3, c4, c5);
}
@Test
public void testGetTimeWiseContiguousDistanceCandidatesOnRightBorder() {
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousDistanceCandidates(competitorCandidates, c5, /* includeStartFrom */ true);
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousCandidates(competitorCandidates, c5, /* includeStartFrom */ true);
assertContainsExactly(result, c1, c2, c3, c4, c5);
}
@Test
public void testGetTimeWiseContiguousDistanceCandidatesOnLeftBorder() {
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousDistanceCandidates(competitorCandidates, c6, /* includeStartFrom */ true);
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousCandidates(competitorCandidates, c6, /* includeStartFrom */ true);
assertContainsExactly(result, c6, c7, c8, c9, c10);
}
@Test
public void testGetTimeWiseContiguousDistanceCandidatesInMiddleOfGapNotInserted() {
final Candidate middleOfGap = candidate(c5.getTimePoint().plus(c5.getTimePoint().until(c6.getTimePoint()).divide(2)), "gap");
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousDistanceCandidates(competitorCandidates, middleOfGap,
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousCandidates(competitorCandidates, middleOfGap,
/* includeStartFrom */ true);
assertContainsExactly(result, c1, c2, c3, c4, c5, middleOfGap, c6, c7, c8, c9, c10);
}
@@ -46,7 +46,7 @@ public class MostProbableCandidatesInSmallTimeRangeFilterTest extends AbstractCa
@Test
public void testGetTimeWiseContiguousDistanceCandidatesInMiddleOfGapNotInsertedDontIncludeStartFrom() {
final Candidate middleOfGap = candidate(c5.getTimePoint().plus(c5.getTimePoint().until(c6.getTimePoint()).divide(2)), "gap");
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousDistanceCandidates(competitorCandidates, middleOfGap,
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousCandidates(competitorCandidates, middleOfGap,
/* includeStartFrom */ false);
assertContainsExactly(result, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10);
}
@@ -55,7 +55,7 @@ public class MostProbableCandidatesInSmallTimeRangeFilterTest extends AbstractCa
public void testGetTimeWiseContiguousDistanceCandidatesInMiddleOfGapInserted() {
final Candidate middleOfGap = candidate(c5.getTimePoint().plus(c5.getTimePoint().until(c6.getTimePoint()).divide(2)), "gap");
competitorCandidates.add(middleOfGap);
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousDistanceCandidates(competitorCandidates, middleOfGap,
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousCandidates(competitorCandidates, middleOfGap,
/* includeStartFrom */ true);
assertContainsExactly(result, c1, c2, c3, c4, c5, middleOfGap, c6, c7, c8, c9, c10);
}
@@ -65,7 +65,7 @@ public class MostProbableCandidatesInSmallTimeRangeFilterTest extends AbstractCa
competitorCandidates.remove(c5);
competitorCandidates.remove(c6);
final Candidate middleOfGap = candidate(c5.getTimePoint().plus(c5.getTimePoint().until(c6.getTimePoint()).divide(2)), "gap");
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousDistanceCandidates(competitorCandidates, middleOfGap,
final NavigableSet<Candidate> result = filter.getTimeWiseContiguousCandidates(competitorCandidates, middleOfGap,
/* includeStartFrom */ true);
assertContainsExactly(result, middleOfGap);
}
@@ -1150,6 +1150,203 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
assertTrue(rankedCompetitors.indexOf(c[0]) == rankedCompetitors.indexOf(c[1])-1);
}
/**
* Tests the {@link LowPointTieBreakBasedOnLastSeriesOnly} scoring scheme's tie breaking rule by setting up a
* leaderboard with a qualification and a final series such that the competitors have equal points but different
* number of wins in the final series, leading to a different order than it would if sorting by the total number
* of wins.
*/
@Test
public void testTieBreakBasedOnLastNonMedalSeriesNoMedal() throws NoWindException {
Competitor[] c = createCompetitors(3).toArray(new Competitor[0]);
Competitor[] q1 = new Competitor[] { c[1], c[0], c[2] }; // c[0] wins no race in the qualification, c[1] wins two,
Competitor[] q2 = new Competitor[] { c[1], c[0], c[2] }; // but that doesn't help c[1] because c[0] wins one in the final
Competitor[] f1 = new Competitor[] { c[2], c[0], c[1] }; // where c[1] wins none. The tie is broken in favor of c[0].
Competitor[] f2 = new Competitor[] { c[0], c[1], c[2] };
Regatta regatta = createRegatta(/* qualifying */2, new String[] { "Default" }, /* final */2, new String[] { "Default" },
/* medal */ false, /* medal */ 0, "testTieBreakWithTieBreakBasedOnLastNonMedalSeriesNoMedal",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY));
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
createAndAttachTrackedRaces(series.get(0), "Default", /* withScores */ true, q1, q2);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", /* withScores */ true, f1, f2);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getNetPoints(c[0], later), leaderboard.getNetPoints(c[1], later), 0.000000001);
assertTrue(leaderboard.getNetPoints(c[0], later) < leaderboard.getNetPoints(c[2], later));
assertTrue(rankedCompetitors.indexOf(c[0]) < rankedCompetitors.indexOf(c[1]));
}
/**
* Tests the {@link LowPointTieBreakBasedOnLastSeriesOnly} scoring scheme's tie breaking rule. c[0] and c[2] have
* equal scores after excluding their worst score each. They both exclude a score from the final series. c[1]'s and
* c[3]'s net points sum is worse than that of c[0] and c[2], so c[1] is not tied. Comparing c[0]'s and c[2]'s
* non-excluded final series scores does not break the tie. They both have as their only non-excluded race a win in
* the final series. So the tie break needs to continue by comparing the sorted non-excluded scores from the
* qualification series. c[2]'s excluded score from the final series is worse than the one c[0] excludes in the
* final series. Yet, in the qualification, c[2] has the better ordered scores, so is expected to be found the
* winner.
*/
@Test
public void testTieBreakBasedOnLastNonMedalSeriesNoMedalOneDiscard() throws NoWindException {
Competitor[] c = createCompetitors(4).toArray(new Competitor[0]);
Competitor[] q1 = new Competitor[] { c[0], c[1], c[2], c[3] }; // c[2]'s net points: 6.0; c[0]'s net points: 6.0
Competitor[] q2 = new Competitor[] { c[2], c[0], c[1], c[3] }; // c[2] has two wins in the qualification, c[0] only one
Competitor[] q3 = new Competitor[] { c[2], c[0], c[1], c[3] };
Competitor[] f1 = new Competitor[] { c[2], c[1], c[0], c[3] }; // c[0] discards this race; remaining is one win in the final series
Competitor[] f2 = new Competitor[] { c[0], c[1], c[3], c[2] }; // c[2] discards this race; remaining is one win in the final series
Regatta regatta = createRegatta(/* qualifying */3, new String[] { "Default" }, /* final */2, new String[] { "Default" },
/* medal */ false, /* medal */ 0, "testTieBreakWithTieBreakBasedOnLastNonMedalSeriesNoMedal",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY));
Leaderboard leaderboard = createLeaderboard(regatta,
/* discarding thresholds: one discard when four races have been completed */ new int[] { 4 });
createAndAttachTrackedRaces(series.get(0), "Default", /* withScores */ true, q1, q2, q3);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", /* withScores */ true, f1, f2);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getNetPoints(c[0], later), leaderboard.getNetPoints(c[2], later), 0.000000001);
assertTrue(rankedCompetitors.indexOf(c[2]) < rankedCompetitors.indexOf(c[0]));
}
/**
* Tests the {@link LowPointTieBreakBasedOnLastSeriesOnly} scoring scheme's tie breaking rule. c[0] and c[2] have
* equal scores after excluding their worst score each. c[0] excludes a score from the final series, c[2] from the
* qualification. The way we understand the rules up to now (see also
* https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4717#c4) we have to sort by series as the primary and by
* score as the secondary criterion, making c[0]'s second score from the top the best score from the qualification,
* whereas for c[2] the second score from the top will be the worst score from the final series. This will break the
* tie in c[0]'s favor.
* <p>
*
* c[1]'s and c[3]'s net points sum is worse than that of c[0] and c[2], so c[1] is not tied.
*/
@Test
public void testTieBreakBasedOnLastNonMedalSeriesNoMedalDiscardsInDifferentSeries() throws NoWindException {
Competitor[] c = createCompetitors(4).toArray(new Competitor[0]);
Competitor[] q1 = new Competitor[] { c[0], c[1], c[3], c[2] }; // c[2] discards this race
Competitor[] q2 = new Competitor[] { c[2], c[0], c[1], c[3] }; // c[2] net points: 6.0; c[0] net points: 6.0
Competitor[] q3 = new Competitor[] { c[2], c[0], c[1], c[3] };
Competitor[] f1 = new Competitor[] { c[2], c[1], c[0], c[3] }; // c[0] discards this race
Competitor[] f2 = new Competitor[] { c[0], c[1], c[2], c[3] }; // c[0] and c[2] won one race in the final series; next, c[2]'s 3.0 points in f2 compare to c[0]'s win in q1
Regatta regatta = createRegatta(/* qualifying */3, new String[] { "Default" }, /* final */2, new String[] { "Default" },
/* medal */ false, /* medal */ 0, "testTieBreakWithTieBreakBasedOnLastNonMedalSeriesNoMedal",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY));
Leaderboard leaderboard = createLeaderboard(regatta,
/* discarding thresholds: one discard when four races have been completed */ new int[] { 4 });
createAndAttachTrackedRaces(series.get(0), "Default", /* withScores */ true, q1, q2, q3);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", /* withScores */ true, f1, f2);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getNetPoints(c[0], later), leaderboard.getNetPoints(c[2], later), 0.000000001);
assertTrue(rankedCompetitors.indexOf(c[0]) < rankedCompetitors.indexOf(c[2]));
}
/**
* Tests the {@link LowPointTieBreakBasedOnLastSeriesOnly} scoring scheme's tie breaking rule by setting up a
* leaderboard with a qualification and a final series such that the competitors have equal points but different
* number of wins in the final series, leading to a different order than it would if sorting by the total number
* of wins.
*/
@Test
public void testTieBreakBasedOnLastNonMedalSeriesNoMedalDecisionByLastRace() throws NoWindException {
Competitor[] c = createCompetitors(3).toArray(new Competitor[0]);
Competitor[] q1 = new Competitor[] { c[1], c[0], c[2] }; // c[0] and c[1] have equal wins and scores,
Competitor[] q2 = new Competitor[] { c[0], c[1], c[2] }; // but c[1] has won the last race
Competitor[] f1 = new Competitor[] { c[0], c[1], c[2] };
Competitor[] f2 = new Competitor[] { c[1], c[0], c[2] };
Regatta regatta = createRegatta(/* qualifying */2, new String[] { "Default" }, /* final */2, new String[] { "Default" },
/* medal */ false, /* medal */ 0, "testTieBreakWithTieBreakBasedOnLastNonMedalSeriesNoMedal",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY));
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
createAndAttachTrackedRaces(series.get(0), "Default", /* withScores */ true, q1, q2);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", /* withScores */ true, f1, f2);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getNetPoints(c[0], later), leaderboard.getNetPoints(c[1], later), 0.000000001);
assertTrue(rankedCompetitors.indexOf(c[1]) < rankedCompetitors.indexOf(c[0])); // based on last race f2
}
/**
* Tests the {@link LowPointTieBreakBasedOnLastSeriesOnly} scoring scheme's tie breaking rule by setting up a
* leaderboard with a qualification and a final series such that the competitors have equal points, and equal
* scores in the final series, but one of them having more wins than the other in the qualification. In this
* case, the qualification counts.
*/
@Test
public void testTieBreakBasedOnLastNonMedalSeriesNoMedalDefaultingToQualification() throws NoWindException {
Competitor[] c = createCompetitors(3).toArray(new Competitor[0]);
Competitor[] q1 = new Competitor[] { c[1], c[0], c[2] }; // c[0] and c[1] have an equal number of wins in the final series and equal total points;
Competitor[] q2 = new Competitor[] { c[2], c[0], c[1] }; // tie breaking is expected to then take the wins in the qualification series into account
Competitor[] f1 = new Competitor[] { c[0], c[1], c[2] }; // where c[1] has one more than c[0]
Competitor[] f2 = new Competitor[] { c[1], c[0], c[2] }; // tie breaking will have to resort to the qualification, finding the win of c[1]
Regatta regatta = createRegatta(/* qualifying */2, new String[] { "Default" }, /* final */2, new String[] { "Default" },
/* medal */ false, /* medal */ 0, "testTieBreakWithTieBreakBasedOnLastNonMedalSeriesNoMedalDefaultingToQualification",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY));
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
createAndAttachTrackedRaces(series.get(0), "Default", /* withScores */ true, q1, q2);
TimePoint later = createAndAttachTrackedRaces(series.get(1), "Default", /* withScores */ true, f1, f2);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getNetPoints(c[0], later), leaderboard.getNetPoints(c[1], later), 0.000000001);
assertTrue(rankedCompetitors.indexOf(c[1]) < rankedCompetitors.indexOf(c[0]));
}
/**
* Tests the {@link LowPointTieBreakBasedOnLastSeriesOnly} scoring scheme's tie breaking rule by setting up a
* leaderboard with a qualification and a final series as well as a medal race such that the competitors have equal
* points but different numbers of wins in the final series
*/
@Test
public void testTieBreakBasedOnLastNonMedalSeriesWithMedal() throws NoWindException {
Competitor[] c = createCompetitors(3).toArray(new Competitor[0]);
Competitor[] q1 = new Competitor[] { c[1], c[0], c[2] }; // c[0] wins no race in the qualification, c[1] wins two,
Competitor[] q2 = new Competitor[] { c[1], c[0], c[2] }; // but that doesn't help c[1] because c[0] wins one in the final
Competitor[] f1 = new Competitor[] { c[2], c[0], c[1] }; // where c[1] wins none. The tie is broken in favor of c[0].
Competitor[] f2 = new Competitor[] { c[0], c[1], c[2] };
Competitor[] m = new Competitor[] { c[0], c[1] }; // c[0] and c[1] got promoted to the medal race, both get disqualified; but in f2 c[2] won, so has to win overall due to count-back
Regatta regatta = createRegatta(/* qualifying */2, new String[] { "Default" }, /* final */2, new String[] { "Default" },
/* medal */ true, /* medal */ 1, "testTieBreakWithTieBreakBasedOnLastNonMedalSeriesWithMedal",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY));
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
createAndAttachTrackedRaces(series.get(0), "Default", /* withScores */ true, q1, q2);
createAndAttachTrackedRaces(series.get(1), "Default", /* withScores */ true, f1, f2);
TimePoint later = createAndAttachTrackedRaces(series.get(2), "Medal", /* withScores */ true, m);
leaderboard.getScoreCorrection().setMaxPointsReason(c[0], series.get(2).getRaceColumns().iterator().next(), MaxPointsReason.DSQ);
leaderboard.getScoreCorrection().setMaxPointsReason(c[1], series.get(2).getRaceColumns().iterator().next(), MaxPointsReason.DSQ);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getNetPoints(c[0], later), leaderboard.getNetPoints(c[1], later), 0.000000001);
assertTrue(rankedCompetitors.indexOf(c[0]) < rankedCompetitors.indexOf(c[1])); // due to more wins in final series
}
/**
* Tests the {@link LowPointTieBreakBasedOnLastSeriesOnly} scoring scheme's tie breaking rule by setting up a
* leaderboard with a qualification and a final series as well as a medal race such that the competitors have equal
* points but different numbers of wins in the final series
*/
@Test
public void testTieBreakBasedOnLastNonMedalSeriesWithMedalDecisionByLastRace() throws NoWindException {
Competitor[] c = createCompetitors(3).toArray(new Competitor[0]);
Competitor[] q1 = new Competitor[] { c[1], c[0], c[2] }; // c[0] and c[1] have equal wins and scores,
Competitor[] q2 = new Competitor[] { c[0], c[1], c[2] }; // but c[1] has won the last race before the medal
Competitor[] f1 = new Competitor[] { c[0], c[1], c[2] };
Competitor[] f2 = new Competitor[] { c[1], c[0], c[2] };
Competitor[] m = new Competitor[] { c[0], c[1] }; // c[0] and c[1] got promoted to the medal race, both get disqualified; but in f2 c[2] won, so has to win overall due to count-back
Regatta regatta = createRegatta(/* qualifying */2, new String[] { "Default" }, /* final */2, new String[] { "Default" },
/* medal */ true, /* medal */ 1, "testTieBreakWithTieBreakBasedOnLastNonMedalSeriesWithMedal",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY));
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
createAndAttachTrackedRaces(series.get(0), "Default", /* withScores */ true, q1, q2);
createAndAttachTrackedRaces(series.get(1), "Default", /* withScores */ true, f1, f2);
TimePoint later = createAndAttachTrackedRaces(series.get(2), "Medal", /* withScores */ true, m);
leaderboard.getScoreCorrection().setMaxPointsReason(c[0], series.get(2).getRaceColumns().iterator().next(), MaxPointsReason.DSQ);
leaderboard.getScoreCorrection().setMaxPointsReason(c[1], series.get(2).getRaceColumns().iterator().next(), MaxPointsReason.DSQ);
List<Competitor> rankedCompetitors = leaderboard.getCompetitorsFromBestToWorst(later);
assertEquals(leaderboard.getNetPoints(c[0], later), leaderboard.getNetPoints(c[1], later), 0.000000001);
assertTrue(rankedCompetitors.indexOf(c[1]) < rankedCompetitors.indexOf(c[0])); // due to last non-medal race
}
/**
* Reported by Clemens Fackeldey:<p>
*
@@ -3,6 +3,8 @@ package com.sap.sailing.domain.leaderboard;
import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import com.sap.sailing.domain.base.Competitor;
@@ -86,12 +88,19 @@ public interface ScoringScheme extends Serializable {
TimePoint timePoint, Leaderboard leaderboard);
/**
* @param competitor1Scores scores of the first competitor, in the order of race columns in the leaderboard
* @param competitor2Scores scores of the second competitor, in the order of race columns in the leaderboard
* @param leaderboard TODO
* @param competitor1Scores
* scores of the first competitor, in the order of race columns in the leaderboard
* @param competitor2Scores
* scores of the second competitor, in the order of race columns in the leaderboard
* @param discardedRaceColumnsPerCompetitor
* for each competitor holds the result of {@link Leaderboard#getResultDiscardingRule()
* Leaderborad.getResultDiscardingRule()}{@code .}{@link ResultDiscardingRule#getDiscardedRaceColumns(Competitor, Leaderboard, Iterable, TimePoint)
* getDiscardedRaceColumns(...)}. This accelerates things considerable because we do not have to make this expensive calculation
* for each competitor again.
*/
int compareByBetterScore(Competitor o1,
List<Util.Pair<RaceColumn, Double>> competitor1Scores, Competitor o2, List<Util.Pair<RaceColumn, Double>> competitor2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard);
int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> competitor1Scores, Competitor o2,
List<Util.Pair<RaceColumn, Double>> competitor2Scores, boolean nullScoresAreBetter, TimePoint timePoint,
Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor);
/**
* In case two competitors scored in different numbers of races, this scoring scheme decides whether this
@@ -103,9 +112,13 @@ public interface ScoringScheme extends Serializable {
ScoringSchemeType getType();
/**
* Usually, when all other sorting criteria end up in a tie, the last race sailed is used to decide.
* @param o1 TODO
* @param o2 TODO
* Usually, when all other sorting criteria end up in a tie, the last race sailed is used to decide, and from there
* backwards. This implements Racing Rules of Sailing (RRS) rule A8.2:
* <p>
*
* <em>"A8.2 If a tie remains between two or more boats, they shall be ranked in order of their scores in the last
* race. Any remaining ties shall be broken by using the tied boats’ scores in the next-to-last race and so on until
* all ties are broken. These scores shall be used even if some of them are excluded scores."</em>
*/
int compareByLastRace(List<Util.Pair<RaceColumn, Double>> o1Scores, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, Competitor o1, Competitor o2);
@@ -3,6 +3,8 @@ package com.sap.sailing.domain.leaderboard.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import com.sap.sailing.domain.base.Competitor;
@@ -55,7 +57,7 @@ public abstract class AbstractHighPointExtremeSailingSeriesOverall extends HighP
* Implements rule 13.5 of the Extreme Sailing Series notice of race as of August 2012.
*/
@Override
public int compareByBetterScore(Competitor o1, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard) {
public int compareByBetterScore(Competitor o1, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor) {
int o1Wins = getWins(o1Scores);
int o2Wins = getWins(o2Scores);
int result = o2Wins - o1Wins;
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
@@ -37,7 +39,7 @@ public abstract class AbstractHighPointFirstGetsFixedOr8AndLastBreaksTie extends
}
@Override
public int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard) {
public int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor) {
Double o1Highest = getHighestScore(o1Scores);
Double o2Highest = getHighestScore(o2Scores);
return o2Highest.compareTo(o1Highest);
@@ -8,6 +8,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
@@ -121,28 +122,41 @@ public abstract class AbstractScoringSchemeImpl implements ScoringScheme {
}
/**
* Assuming both competitors scored in the same number of races, compares the sorted scores.
* Assuming both competitors scored in the same number of races, compares the sorted scores based on World Sailing's
* Racing Rules of Sailing (RRS) addendum A8.1:<p>
*
* <em>"A8.1 If there is a series-score tie between two or more boats, each boat’s race scores shall be listed in
* order of best to worst, and at the first point(s) where there is a difference the tie shall be broken in favour
* of the boat(s) with the best score(s). No excluded scores shall be used."</em>
*/
@Override
public int compareByBetterScore(Competitor o1, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard) {
final Comparator<Double> pureScoreComparator = getScoreComparator(nullScoresAreBetter);
public int compareByBetterScore(Competitor o1, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o1Scores,
Competitor o2, List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter,
TimePoint timePoint, Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor) {
final Comparator<Pair<RaceColumn, Double>> ruleA8_1ScoreComparator = getRuleA8_1ScoreComparator(nullScoresAreBetter);
// needs to compare net points; therefore, divide the total points by the column factor for comparison:
List<Double> o1NetScores = new ArrayList<>();
List<Pair<RaceColumn, Double>> o1NetScores = new ArrayList<>();
final Set<RaceColumn> o1Discards = discardedRaceColumnsPerCompetitor.get(o1);
for (com.sap.sse.common.Util.Pair<RaceColumn, Double> o1ColumnAndScore : o1Scores) {
o1NetScores.add(o1ColumnAndScore.getB() / getScoreFactor(o1ColumnAndScore.getA()));
if (!o1Discards.contains(o1ColumnAndScore.getA())) {
o1NetScores.add(new Pair<>(o1ColumnAndScore.getA(), o1ColumnAndScore.getB() / getScoreFactor(o1ColumnAndScore.getA())));
}
}
List<Double> o2NetScores = new ArrayList<>();
List<Pair<RaceColumn, Double>> o2NetScores = new ArrayList<>();
final Set<RaceColumn> o2Discards = discardedRaceColumnsPerCompetitor.get(o2);
for (com.sap.sse.common.Util.Pair<RaceColumn, Double> o2ColumnAndScore : o2Scores) {
o2NetScores.add(o2ColumnAndScore.getB() / getScoreFactor(o2ColumnAndScore.getA()));
if (!o2Discards.contains(o2ColumnAndScore.getA())) {
o2NetScores.add(new Pair<>(o2ColumnAndScore.getA(), o2ColumnAndScore.getB() / getScoreFactor(o2ColumnAndScore.getA())));
}
}
Collections.sort(o1NetScores, pureScoreComparator);
Collections.sort(o2NetScores, pureScoreComparator);
Collections.sort(o1NetScores, ruleA8_1ScoreComparator);
Collections.sort(o2NetScores, ruleA8_1ScoreComparator);
// now both lists are sorted from best to worst score
Iterator<Double> o1Iter = o1NetScores.iterator();
Iterator<Double> o2Iter = o2NetScores.iterator();
Iterator<Pair<RaceColumn, Double>> o1Iter = o1NetScores.iterator();
Iterator<Pair<RaceColumn, Double>> o2Iter = o2NetScores.iterator();
int result = 0;
while (result == 0 && o1Iter.hasNext() && o2Iter.hasNext()) {
result = pureScoreComparator.compare(o1Iter.next(), o2Iter.next());
result = getScoreComparator(nullScoresAreBetter).compare(o1Iter.next().getB(), o2Iter.next().getB());
}
if (o1Iter.hasNext() != o2Iter.hasNext()) {
// if, as may be allowed by some scoring scheme variants, competitors with different numbers of scored races are compared
@@ -152,6 +166,16 @@ public abstract class AbstractScoringSchemeImpl implements ScoringScheme {
return result;
}
/**
* Obtains a comparator that compares two non-discarded scores according the rule A8.1, or any
* modification thereof (which subclasses can provide by overriding this method). This default implementation
* simply uses the {@link #getScoreComparator(boolean) score comparator} to compare the net scores
* directly.
*/
protected Comparator<Pair<RaceColumn, Double>> getRuleA8_1ScoreComparator(boolean nullScoresAreBetter) {
return (p1, p2)->getScoreComparator(nullScoresAreBetter).compare(p1.getB(), p2.getB());
}
/**
* By default, this scoring scheme implementation does not compare the numbers of races scored.
*/
@@ -161,8 +185,18 @@ public abstract class AbstractScoringSchemeImpl implements ScoringScheme {
}
/**
* @param o1ScoresIncludingDiscarded scores that include the points for those races that have been discarded (total points)
* @param o2ScoresIncludingDiscarded scores that include the points for those races that have been discarded (total points)
* Looks backwards starting at the last race until the first score difference is found, including the discarded
* scored. This implements Racing Rules of Sailing (RRS) section A8.2:
* <p>
*
* <em>"A8.2 If a tie remains between two or more boats, they shall be ranked in order of their scores in the last race.
* Any remaining ties shall be broken by using the tied boats’ scores in the next-to-last race and so on until all
* ties are broken. These scores shall be used even if some of them are excluded scores."</em>
*
* @param o1ScoresIncludingDiscarded
* scores that include the points for those races that have been discarded (total points)
* @param o2ScoresIncludingDiscarded
* scores that include the points for those races that have been discarded (total points)
*/
@Override
public int compareByLastRace(List<com.sap.sse.common.Util.Pair<RaceColumn, Double>> o1ScoresIncludingDiscarded,
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
@@ -22,7 +24,7 @@ public class HighPointFirstGets10LastBreaksTie extends HighPointFirstGetsFixedSc
}
@Override
public int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard) {
public int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor) {
return 0;
}
}
@@ -6,6 +6,7 @@ import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
@@ -55,7 +56,7 @@ public class HighPointFirstGets1LastBreaksTie extends HighPointFirstGetsFixedSco
@Override
public int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2,
List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard) {
List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor) {
// Construct a graph in which all competitors with equal points are represented as nodes;
// edges represent a RaceColumn/Fleet where the "from" node in the edge has won over the "to"
// node in the edge. This graph will be sorted such that competitors precede those over which
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
@@ -21,7 +23,7 @@ public class HighPointLastBreaksTie extends HighPoint {
private static final long serialVersionUID = -5338636946886101669L;
@Override
public int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard) {
public int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2, List<Util.Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor) {
return 0;
}
@@ -55,6 +55,7 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
private final ScoringScheme scoringScheme;
private final Map<Util.Pair<Competitor, RaceColumn>, Double> netPointsCache;
private final Map<Util.Pair<Competitor, RaceColumn>, Double> totalPointsCache;
private final Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor;
private final boolean nullScoresAreBetter;
private final TimePoint timePoint;
@@ -84,11 +85,13 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
this.timePoint = timePoint;
this.scoringScheme = scoringScheme;
this.nullScoresAreBetter = nullScoresAreBetter;
netPointsCache = new HashMap<Util.Pair<Competitor, RaceColumn>, Double>();
totalPointsCache = new HashMap<Util.Pair<Competitor, RaceColumn>, Double>();
netPointsCache = new HashMap<>();
totalPointsCache = new HashMap<>();
discardedRaceColumnsPerCompetitor = new HashMap<>();
for (Competitor competitor : leaderboard.getCompetitors()) {
Set<RaceColumn> discardedRaceColumns = leaderboard.getResultDiscardingRule().getDiscardedRaceColumns(
competitor, leaderboard, raceColumnsToConsider, timePoint);
this.discardedRaceColumnsPerCompetitor.put(competitor, discardedRaceColumns);
for (RaceColumn raceColumn : raceColumnsToConsider) {
Pair<Competitor, RaceColumn> key = new Util.Pair<Competitor, RaceColumn>(competitor, raceColumn);
netPointsCache.put(key, leaderboard.getNetPoints(competitor, raceColumn, timePoint, discardedRaceColumns));
@@ -471,11 +474,12 @@ public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
/**
* Assuming both competitors scored in the same number of races, and assuming they scored the same net score,
* break the tie according to the {@link #scoringScheme scoring scheme} set for this comparator.
* @see ScoringScheme#compareByBetterScore(Competitor, List, Competitor, List, boolean, TimePoint, Leaderboard)
* @see ScoringScheme#compareByBetterScore(Competitor, List, Competitor, List, boolean, TimePoint, Leaderboard, Map)
*/
protected int compareByBetterScore(Competitor o1, List<Util.Pair<RaceColumn, Double>> o1Scores, Competitor o2,
List<Util.Pair<RaceColumn, Double>> o2Scores, TimePoint timePoint) {
return scoringScheme.compareByBetterScore(o1, o1Scores, o2, o2Scores, nullScoresAreBetter, timePoint, leaderboard);
return scoringScheme.compareByBetterScore(o1, o1Scores, o2, o2Scores, nullScoresAreBetter, timePoint, leaderboard,
Collections.unmodifiableMap(discardedRaceColumnsPerCompetitor));
}
/**
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -41,7 +43,7 @@ public class LowPointForLeagueOverallLeaderboard extends LowPoint {
*/
@Override
public int compareByBetterScore(Competitor o1, List<Pair<RaceColumn, Double>> o1Scores,
Competitor o2, List<Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard) {
Competitor o2, List<Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter, TimePoint timePoint, Leaderboard leaderboard, Map<Competitor, Set<RaceColumn>> discardedRaceColumnsPerCompetitor) {
final Double o1ScoreSum = o1Scores.stream().collect(Collectors.summingDouble(rcAndScore->rcAndScore.getB()));
final Double o2ScoreSum = o2Scores.stream().collect(Collectors.summingDouble(rcAndScore->rcAndScore.getB()));
assert Math.abs(o1ScoreSum - o2ScoreSum) < 0.00001;
@@ -1,6 +1,13 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.util.Comparator;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceColumnInSeries;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sse.common.Util.Pair;
public class LowPointTieBreakBasedOnLastSeriesOnly extends LowPoint {
private static final long serialVersionUID = -2837189757937229157L;
@@ -9,4 +16,59 @@ public class LowPointTieBreakBasedOnLastSeriesOnly extends LowPoint {
public ScoringSchemeType getType() {
return ScoringSchemeType.LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY;
}
/**
* Obtains a comparator that compares two non-discarded, non medal-race scores according the rule 21.9:
* <p>
*
* <em>"21.9 RRS A8 is changed as follows: 21.9.1 For boats assigned to compete in a medal race, ties in the regatta
* score will be broken by the medal race score. This changes RRS A8. 21.9.2 For tied boats with the same points
* score in the medal race, ties will be broken applying RRS A8 to the opening series scores. 21.9.3 For boats that
* sailed a Qualifying Series and a Final Series, ties will be broken using A8 but using the scores in the Final
* Series before using any scores in the Qualifying Series when applying A8.1. This applies also to boats that were
* tied after the medal race and had the same score in the medal race."</em>
* <p>
*
* For this, the position of the series in the regatta is determined, and if one score comes from the last non-medal
* series and the other does not, the one from the last non-medal series is considered better. Otherwise, the
* {@link #getScoreComparator(boolean) score comparator} is used to compare the scores numerically.
*/
@Override
protected Comparator<Pair<RaceColumn, Double>> getRuleA8_1ScoreComparator(boolean nullScoresAreBetter) {
return (Pair<RaceColumn, Double> p1, Pair<RaceColumn, Double> p2)->{
final int result;
if (isFromLastNonMedalSeries(p1) != isFromLastNonMedalSeries(p2)) {
result = isFromLastNonMedalSeries(p1) ? -1 // p1 is better, so less, than p2
: 1; // p1 is worse, so greater, than p2
} else {
result = getScoreComparator(nullScoresAreBetter).compare(p1.getB(), p2.getB());
}
return result;
};
}
private boolean isFromLastNonMedalSeries(Pair<RaceColumn, Double> raceColumnAndNetPoints) {
final RaceColumn raceColumn = raceColumnAndNetPoints.getA();
final boolean result;
if (raceColumn instanceof RaceColumnInSeries) {
final Series series = ((RaceColumnInSeries) raceColumn).getSeries();
final Regatta regatta = series.getRegatta();
boolean found = false;
boolean lastNonMedal = true;
for (final Series seriesInRegatta : regatta.getSeries()) {
if (!found) {
if (seriesInRegatta == series) {
found = true;
}
} else if (!seriesInRegatta.isMedal()) {
lastNonMedal = false; // already found, and seriesInRegatta is a non-medal series that comes after series
}
}
assert found;
result = lastNonMedal;
} else {
result = !raceColumn.isMedalRace();
}
return result;
}
}
@@ -20,6 +20,13 @@ import com.sap.sse.common.Timed;
public interface Candidate extends Comparable<CandidateImpl>, Timed {
Waypoint getWaypoint();
/**
* Is this a candidate for a fixed mark passing?
*/
default boolean isFixed() {
return false;
}
int getOneBasedIndexOfWaypoint();
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.markpassingcalculation;
import java.lang.Thread.State;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -507,8 +508,13 @@ public class MarkPassingCalculator {
queue.add(update);
// regardless of whether the queue is empty or not, launch the thread if it doesn't run yet and we are not suspended;
// the queue may have filled up while we were suspended
if (!suspended && listenerThread == null) {
listenerThread = createAndStartListenerThread();
if (!suspended) {
if (listenerThread == null) {
listenerThread = createAndStartListenerThread();
} else if (listenerThread.getState() == State.TERMINATED) {
logger.severe("Listener thread of MarkPassingCalculator (MPC) for race "+race.getRace().getName()+
" terminated but not null. Why are we still receiving updates? We must have been stopped before!");
}
}
}
}
@@ -474,7 +474,7 @@ public class CandidateChooserImpl implements CandidateChooser {
public void setFixedPassing(Competitor c, Integer zeroBasedIndexOfWaypoint, TimePoint t) {
LockUtil.lockForWrite(perCompetitorLocks.get(c));
try {
Candidate fixedCan = new CandidateImpl(zeroBasedIndexOfWaypoint + 1, t, 1, Util.get(race.getRace().getCourse().getWaypoints(), zeroBasedIndexOfWaypoint));
Candidate fixedCan = new CandidateForFixedMarkPassingImpl(zeroBasedIndexOfWaypoint + 1, t, 1, Util.get(race.getRace().getCourse().getWaypoints(), zeroBasedIndexOfWaypoint));
NavigableSet<Candidate> fixed = fixedPassings.get(c);
if (fixed != null) { // can only set the mark passing if the competitor is still part of this race
if (!fixed.add(fixedCan)) {
@@ -0,0 +1,17 @@
package com.sap.sailing.domain.markpassingcalculation.impl;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sse.common.TimePoint;
public class CandidateForFixedMarkPassingImpl extends CandidateImpl {
private static final long serialVersionUID = 3657502693032556232L;
public CandidateForFixedMarkPassingImpl(int oneBasedIndexOfWaypoint, TimePoint p, double probability, Waypoint w) {
super(oneBasedIndexOfWaypoint, p, probability, w);
}
@Override
public boolean isFixed() {
return true;
}
}
@@ -102,7 +102,7 @@ public class MostProbableCandidatesInSmallTimeRangeFilter {
while (!newCandidatesModifiableCopy.isEmpty()) {
final Candidate nextNewCandidate = newCandidatesModifiableCopy.iterator().next();
newCandidatesModifiableCopy.remove(nextNewCandidate);
final NavigableSet<Candidate> contiguousSequenceForNextNewCandidate = getTimeWiseContiguousDistanceCandidates(competitorCandidates, nextNewCandidate, /* includeStartFrom */ true);
final NavigableSet<Candidate> contiguousSequenceForNextNewCandidate = getTimeWiseContiguousCandidates(competitorCandidates, nextNewCandidate, /* includeStartFrom */ true);
disjointSequencesAffectedByNewAndRemovedCandidates.add(contiguousSequenceForNextNewCandidate);
// remove the candidate grouped in the sequence from the remaining new candidates to consider
// because they have been "scooped up" by this sequence already and need no further consideration:
@@ -122,7 +122,7 @@ public class MostProbableCandidatesInSmallTimeRangeFilter {
while (!removedCandidatesModifiableCopy.isEmpty()) {
final Candidate nextRemovedCandidate = removedCandidatesModifiableCopy.iterator().next();
removedCandidatesModifiableCopy.remove(nextRemovedCandidate);
final NavigableSet<Candidate> contiguousSequenceForNextRemovedCandidate = getTimeWiseContiguousDistanceCandidates(competitorCandidates, nextRemovedCandidate, /* includeStartFrom */ false);
final NavigableSet<Candidate> contiguousSequenceForNextRemovedCandidate = getTimeWiseContiguousCandidates(competitorCandidates, nextRemovedCandidate, /* includeStartFrom */ false);
removeAllRemovedCandidatesInOrNearSequence(contiguousSequenceForNextRemovedCandidate, removedCandidatesModifiableCopy);
// If adjacent sequences were added before and after the removed candidate,
// we need to distinguish whether the gap around the removed candidate was greater
@@ -233,7 +233,7 @@ public class MostProbableCandidatesInSmallTimeRangeFilter {
* @param includeStartFrom
* whether or not to include {@code startFrom} in the resulting set
*/
public NavigableSet<Candidate> getTimeWiseContiguousDistanceCandidates(NavigableSet<Candidate> competitorCandidates, Candidate startFrom, boolean includeStartFrom) {
public NavigableSet<Candidate> getTimeWiseContiguousCandidates(NavigableSet<Candidate> competitorCandidates, Candidate startFrom, boolean includeStartFrom) {
final NavigableSet<Candidate> result = new TreeSet<>(candidateComparator);
if (includeStartFrom) {
result.add(startFrom);
@@ -89,7 +89,7 @@ public class StationarySequence {
// borders of this sequence:
final TimeRange timeRangeNoLongerPassingFilter = getExtendedEndBorderRange(extendedBy);
if (timeRangeNoLongerPassingFilter != null) {
removeFromFilterResult(timeRangeNoLongerPassingFilter, candidatesEffectivelyAdded, candidatesEffectivelyRemoved);
removeFromFilterResultUnlessFixed(timeRangeNoLongerPassingFilter, candidatesEffectivelyAdded, candidatesEffectivelyRemoved);
}
}
return bounds != null;
@@ -108,7 +108,7 @@ public class StationarySequence {
if (bounds != null) {
track.lockForRead();
try {
final Iterator<GPSFixMoving> iter = track.getFixesIterator(start.getTimePoint(), /* inclusive */ true,
final Iterator<GPSFixMoving> iter = track.getRawFixesIterator(start.getTimePoint(), /* inclusive */ true,
end.getTimePoint(), /* inclusive */ true);
while (iter.hasNext()) {
final GPSFixMoving fix = iter.next();
@@ -158,7 +158,7 @@ public class StationarySequence {
// borders of this sequence:
final TimeRange timeRangeNoLongerPassingFilter = getExtendedStartBorderRange(extendedBy);
if (timeRangeNoLongerPassingFilter != null) {
removeFromFilterResult(timeRangeNoLongerPassingFilter, candidatesEffectivelyAdded, candidatesEffectivelyRemoved);
removeFromFilterResultUnlessFixed(timeRangeNoLongerPassingFilter, candidatesEffectivelyAdded, candidatesEffectivelyRemoved);
}
}
return bounds != null;
@@ -204,11 +204,15 @@ public class StationarySequence {
return result;
}
private void removeFromFilterResult(final TimeRange timeRangeNoLongerPassingFilter, Set<Candidate> candidatesEffectivelyAdded,
private void removeFromFilterResultUnlessFixed(final TimeRange timeRangeNoLongerPassingFilter, Set<Candidate> candidatesEffectivelyAdded,
Set<Candidate> candidatesEffectivelyRemoved) {
final SortedSet<Candidate> candidatesNoLongerPassingFilter = getCandidatesInTimeRange(timeRangeNoLongerPassingFilter);
candidatesEffectivelyAdded.removeAll(candidatesNoLongerPassingFilter);
candidatesEffectivelyRemoved.addAll(candidatesNoLongerPassingFilter);
for (final Candidate candidate : candidatesNoLongerPassingFilter) {
if (!candidate.isFixed()) {
candidatesEffectivelyAdded.removeAll(candidatesNoLongerPassingFilter);
candidatesEffectivelyRemoved.addAll(candidatesNoLongerPassingFilter);
}
}
}
private SortedSet<Candidate> getCandidatesInTimeRange(final TimeRange timeRange) {
@@ -219,7 +223,16 @@ public class StationarySequence {
}
public Iterable<Candidate> getValidCandidates() {
return ()->candidates.stream().filter(c->isCloseEnoughToSequenceBorder(c)).iterator();
return ()->candidates.stream().filter(c->isValidCandidate(c)).iterator();
}
/**
* A candidate that is part of this stationary sequence is considered valid if it is time-wise close
* enough to one of the sequence's borders (see {@link #CANDIDATE_FILTER_TIME_WINDOW}) or if it is
* a candidate for a {@link Candidate#isFixed() fixed mark passing}.
*/
private boolean isValidCandidate(Candidate c) {
return c.isFixed() || isCloseEnoughToSequenceBorder(c);
}
private boolean isCloseEnoughToSequenceBorder(Candidate candidate) {
@@ -246,7 +259,7 @@ public class StationarySequence {
assert !candidates.contains(candidate) && !getFirst().getTimePoint().after(candidate.getTimePoint()) &&
!getLast().getTimePoint().before(candidate.getTimePoint());
candidates.add(candidate);
if (isCloseEnoughToSequenceBorder(candidate)) {
if (isValidCandidate(candidate)) {
candidatesEffectivelyAdded.add(candidate);
candidatesEffectivelyRemoved.remove(candidate);
}
@@ -269,7 +282,7 @@ public class StationarySequence {
void remove(Candidate candidate, Set<Candidate> candidatesEffectivelyAdded, Set<Candidate> candidatesEffectivelyRemoved,
NavigableSet<StationarySequence> stationarySequenceSetToUpdate) {
assert candidates.contains(candidate);
final boolean wasValidCandidate = isCloseEnoughToSequenceBorder(candidate);
final boolean wasValidCandidate = isValidCandidate(candidate);
final boolean wasFirst = candidate == getFirst();
final boolean wasLast = candidate == getLast();
if (wasFirst || size() == 2) { // if size() == 2 then it will shrink to 1 and this sequence shall be removed
@@ -322,7 +335,7 @@ public class StationarySequence {
* If no estimated position can be obtained, {@code null} is returned.
*/
private Bounds createNewBounds(Candidate candidate) {
final Position estimatedPosition = track.getEstimatedPosition(candidate.getTimePoint(), /* extrapolate */ false);
final Position estimatedPosition = track.getEstimatedPosition(candidate.getTimePoint(), /* extrapolate */ true);
return estimatedPosition == null ? null : new BoundsImpl(estimatedPosition);
}
@@ -235,10 +235,11 @@ public class StationarySequenceBasedFilter {
*/
private void addCandidate(Candidate newCandidate,
Set<Candidate> candidatesEffectivelyAdded, Set<Candidate> candidatesEffectivelyRemoved) {
if (candidates.contains(newCandidate)) {
boolean candidatesContainsNewCandidate = candidates.contains(newCandidate);
if (candidatesContainsNewCandidate) {
logger.severe("Candidates "+candidates+" already contain "+newCandidate+" which is to be added.");
}
final boolean assertion = !candidates.contains(newCandidate) && isCandidatesConsistent();
final boolean assertion = !candidatesContainsNewCandidate && isCandidatesConsistent();
assert assertion;
if (newCandidate == startProxyCandidate) {
candidatesEffectivelyAdded.add(newCandidate);
@@ -539,13 +540,10 @@ public class StationarySequenceBasedFilter {
}
}
if (fixesReplacingExistingOnes != null) {
Set<GPSFixMoving> newFixesHashedForQuickAssertionCheck = new HashSet<>();
assert Util.addAll(newFixes, newFixesHashedForQuickAssertionCheck) != null;
for (final GPSFixMoving fixReplacingExistingOne : fixesReplacingExistingOnes) {
final boolean assertion2 = Util.contains(newFixes, fixReplacingExistingOne);
if (!assertion2) {
logger.severe("Expected "+fixesReplacingExistingOnes+" to be part of the "+Util.size(newFixes)+
" new fixes, but it wasn't");
}
assert assertion2;
assert newFixesHashedForQuickAssertionCheck.contains(fixReplacingExistingOne);
final Candidate dummyCandidateForReplacementFix = StationarySequence.createDummyCandidate(fixReplacingExistingOne.getTimePoint());
final StationarySequence dummyStationarySequenceForFix = createStationarySequence(dummyCandidateForReplacementFix);
final StationarySequence lastSequenceStartingAtOrBeforeFix = stationarySequences.floor(dummyStationarySequenceForFix);
@@ -557,9 +557,9 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
@Override
public void raceRemoved(TrackedRace trackedRace) {
if (trackedRace == TrackedRaceImpl.this) {
// stop mark passing calculator when tracked race is removed:
markPassingCalculator.stop();
}
// stop mark passing calculator when tracked race is removed:
markPassingCalculator.stop();
}
}
}, /* Not relevant For replication */ Optional.empty(), /* synchronous */ false);
} else {
@@ -267,7 +267,7 @@ boatChanges=Boat Changes
pairingListTemplate=Pairing list template
printHint=Prints the applied version
blockedApplyButton=Registered Competitors are unequal to Competitors from Pairinglist!
multiplierInfo=Multipes flights and create them next to each other so that a competition with less boatchanges is possible
multiplierInfo=Multiplies flights and creates them next to each other so that a competition with fewer boat changes is possible
noPairingListAvailable=The print function is only available when a pairing list has already been applied to the selected leaderboards race logs.
noEventsFound=No events were found
noEventSelected=No event selected
@@ -2382,7 +2382,6 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
public CoursePositionsDTO getCoursePositions(RegattaAndRaceIdentifier raceIdentifier, Date date) {
CoursePositionsDTO result = new CoursePositionsDTO();
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
getSecurityService().checkCurrentUserReadPermission(trackedRace);
if (trackedRace != null) {
getSecurityService().checkCurrentUserReadPermission(trackedRace);
final TimePoint dateAsTimePoint;
@@ -196,10 +196,17 @@ public class BoatMarkVectorGraphics extends AbstractMarkVectorGraphics {
private Bearing bearingOrReverseDependingOnXTEToOther(Position pos, Bearing bearing, Position other) {
final Bearing result;
if (pos.crossTrackError(other, bearing).compareTo(Distance.NULL) > 0) {
result = bearing.reverse();
if (bearing == null) {
// no start line bearing is known; assume that the start boat is on the
// starboard side of the line and that the line is approximately
// perpendicular to the bearing to the next mark:
result = pos.getBearingGreatCircle(other).add(new DegreeBearingImpl(-90));
} else {
result = bearing;
if (pos.crossTrackError(other, bearing).compareTo(Distance.NULL) > 0) {
result = bearing.reverse();
} else {
result = bearing;
}
}
return result;
}
@@ -17,6 +17,7 @@ public class RegattaJsonSerializer implements JsonSerializer<Regatta> {
public static final String FIELD_START_DATE = "startDate";
public static final String FIELD_END_DATE = "endDate";
public static final String FIELD_SCORINGSYSTEM = "scoringSystem";
public static final String FIELD_RANKINGMETRIC = "rankingMetric";
public static final String FIELD_SERIES = "series";
public static final String FIELD_COMPETITORS = "competitors";
public static final String FIELD_BOATS = "boats";
@@ -49,6 +50,7 @@ public class RegattaJsonSerializer implements JsonSerializer<Regatta> {
result.put(FIELD_START_DATE, regatta.getStartDate() != null ? regatta.getStartDate().asMillis() : null);
result.put(FIELD_END_DATE, regatta.getEndDate() != null ? regatta.getEndDate().asMillis() : null);
result.put(FIELD_SCORINGSYSTEM, regatta.getScoringScheme().getType().name());
result.put(FIELD_RANKINGMETRIC, regatta.getRankingMetricType().name());
result.put(FIELD_BOATCLASS, regatta.getBoatClass() != null ? regatta.getBoatClass().getName() : null);
result.put(FIELD_COURSE_AREA_ID,
regatta.getDefaultCourseArea() != null ? regatta.getDefaultCourseArea().getId().toString() : null);
@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.pde.ui.EquinoxLauncher">
<booleanAttribute key="append.args" value="true"/>
<booleanAttribute key="automaticAdd" value="false"/>
<booleanAttribute key="automaticValidate" value="false"/>
<stringAttribute key="bootstrap" value=""/>
<stringAttribute key="checked" value="[NONE]"/>
<booleanAttribute key="clearConfig" value="false"/>
<booleanAttribute key="com.sap.jvm.profiling.ui.widgets.allowDebugging" value="false"/>
<stringAttribute key="configLocation" value="${workspace_loc}/target"/>
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="false"/>
<intAttribute key="default_start_level" value="4"/>
<booleanAttribute key="includeOptional" 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_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;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">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<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.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=5010 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -Dpersistentcompetitors.clear=false -XX:+UseMembar -Dpolardata.source.url=https://www.sapsailing.com -Drestore.tracked.races=true"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="profilingTraceType-ALLOCATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%INCREASE_COUNT%CTX_KEY%8192%CTX_ENTRY%KEY_MIN_SIZE%CTX_KEY%32%CTX_ENTRY%KEY_MAX_SIZE%CTX_KEY%65536%CTX_ENTRY%KEY_INC_LINE_NRS%CTX_KEY%true%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%CLASS_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ADAPTIVE%CTX_KEY%false%CTX_ENTRY%"/>
<stringAttribute key="profilingTraceType-IO_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-METHOD_PARAMETER_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-NETWORK_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_RESOLVE_ALL_HOSTS%CTX_KEY%true%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%"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.rabbitmq.client@default:default,com.sun.activation.javax.activation@default:default,com.sun.istack.commons-runtime@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,com.sun.xml.bind.jaxb-impl@default:default,jackson-core-asl@default:default,jackson-jaxrs@default:default,jackson-mapper-asl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,javax.xml.stream@default:default,javax.xml.ws@default:default,javax.xml@default:default,jaxb-api@default:default,jcl.over.slf4j@default:default,lz4-java@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.felix.shell.remote@0:true,org.apache.felix.shell@0:true,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.poi.ooxml.schemas@default:default,org.apache.poi.ooxml@default:default,org.apache.poi@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.apache.xmlbeans@default:default,org.dom4j@default:default,org.eclipse.equinox.cm@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.equinox.launcher@default:default,org.eclipse.equinox.simpleconfigurator@2:true,org.eclipse.jetty.client@default:default,org.eclipse.jetty.deploy@4:true,org.eclipse.jetty.http@4:true,org.eclipse.jetty.io@4:true,org.eclipse.jetty.jmx@4:true,org.eclipse.jetty.osgi.boot@3:true,org.eclipse.jetty.security@4:true,org.eclipse.jetty.server@4:true,org.eclipse.jetty.servlet@4:true,org.eclipse.jetty.util@4:true,org.eclipse.jetty.webapp@4:true,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.xml@4:true,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.hyperic.sigar@default:default,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
<stringAttribute key="workspace_bundles" value="com.google.gwt.servlet@default:default,com.googlecode.java-diff-utils@default:default,com.sap.sailing.barbados.resultimport@4:true,com.sap.sailing.competitorimport@default:default,com.sap.sailing.dashboards.gwt@6:true,com.sap.sailing.datamining.provider@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@5:true,com.sap.sailing.declination@default:default,com.sap.sailing.domain.bravoadapter@5:true,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@5:true,com.sap.sailing.domain.expeditionadapter@5:true,com.sap.sailing.domain.igtimiadapter.gateway@5:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@4:true,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@4:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@4:true,com.sap.sailing.domain.swisstimingadapter@5:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@4:true,com.sap.sailing.domain.tractracadapter@5:true,com.sap.sailing.domain.windfinderadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@4:true,com.sap.sailing.expeditionconnector.common@default:default,com.sap.sailing.expeditionconnector.persistence@4:true,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@4:true,com.sap.sailing.geocoding@default:default,com.sap.sailing.grib@default:default,com.sap.sailing.gwt.ui@6:true,com.sap.sailing.kiworesultimport@4:true,com.sap.sailing.manage2sail.resultimport@4:true,com.sap.sailing.manage2sail@default:default,com.sap.sailing.monitoring@7:true,com.sap.sailing.news@4:true,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.polars.datamining.shared@default:default,com.sap.sailing.polars.datamining@5:true,com.sap.sailing.polars@5:true,com.sap.sailing.resultimport@4:true,com.sap.sailing.routeconverterjava11extension@default:false,com.sap.sailing.sailwave.resultimport@4:true,com.sap.sailing.server.gateway.serialization.shared.android@default:default,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@5:true,com.sap.sailing.server.interface@default:default,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@5:true,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@4:true,com.sap.sailing.www@5:true,com.sap.sailing.xmlexport@5:true,com.sap.sailing.xrr.resultimport@4:true,com.sap.sailing.xrr.schema@default:default,com.sap.sailing.xrr.structureimport@default:default,com.sap.sailing.yachtscoring.resultimport@4:true,com.sap.sse.common@default:default,com.sap.sse.datamining.annotations@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining.ui@default:default,com.sap.sse.datamining@default:default,com.sap.sse.filestorage@4:true,com.sap.sse.gwt.adminconsole@default:default,com.sap.sse.gwt@default:default,com.sap.sse.jersey.jaxbdependencyfragment@default:false,com.sap.sse.jettyextensions@default:false,com.sap.sse.mail@5:true,com.sap.sse.mongodb@default:default,com.sap.sse.operationaltransformation@default:default,com.sap.sse.replication.interfaces@default:default,com.sap.sse.replication@6:true,com.sap.sse.security.common@default:default,com.sap.sse.security.interface@default:default,com.sap.sse.security.persistence@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security@default:default,com.sap.sse.shared.android@default:default,com.sap.sse.threadmanager@default:default,com.sap.sse@default:default,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default,org.mp4parser.isoparser@default:default"/>
<booleanAttribute key="append.args" value="true"/>
<booleanAttribute key="automaticAdd" value="false"/>
<booleanAttribute key="automaticValidate" value="false"/>
<stringAttribute key="bootstrap" value=""/>
<stringAttribute key="checked" value="[NONE]"/>
<booleanAttribute key="clearConfig" value="false"/>
<booleanAttribute key="com.sap.jvm.profiling.ui.widgets.allowDebugging" value="false"/>
<stringAttribute key="configLocation" value="${workspace_loc}/target"/>
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="false"/>
<intAttribute key="default_start_level" value="4"/>
<booleanAttribute key="includeOptional" 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_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;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">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<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.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=5010 -Xmx6000m -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -Dpersistentcompetitors.clear=false -XX:+UseMembar -Dpolardata.source.url=https://www.sapsailing.com -Drestore.tracked.races=true"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="profilingTraceType-ALLOCATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%INCREASE_COUNT%CTX_KEY%8192%CTX_ENTRY%KEY_MIN_SIZE%CTX_KEY%32%CTX_ENTRY%KEY_MAX_SIZE%CTX_KEY%65536%CTX_ENTRY%KEY_INC_LINE_NRS%CTX_KEY%true%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%CLASS_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ADAPTIVE%CTX_KEY%false%CTX_ENTRY%"/>
<stringAttribute key="profilingTraceType-IO_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-METHOD_PARAMETER_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-NETWORK_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_RESOLVE_ALL_HOSTS%CTX_KEY%true%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%"/>
<booleanAttribute key="show_selected_only" value="false"/>
<stringAttribute key="target_bundles" value="com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.rabbitmq.client@default:default,com.sun.activation.javax.activation@default:default,com.sun.istack.commons-runtime@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,com.sun.xml.bind.jaxb-impl@default:default,jackson-core-asl@default:default,jackson-jaxrs@default:default,jackson-mapper-asl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,javax.xml.stream@default:default,javax.xml.ws@default:default,javax.xml@default:default,jaxb-api@default:default,jcl.over.slf4j@default:default,lz4-java@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.fileupload@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.apache.commons.math@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.felix.shell.remote@0:true,org.apache.felix.shell@0:true,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.poi.ooxml.schemas@default:default,org.apache.poi.ooxml@default:default,org.apache.poi@default:default,org.apache.servicemix.bundles.aws-java-sdk@default:default,org.apache.servicemix.bundles.ehcache@default:default,org.apache.servicemix.bundles.scribe@default:default,org.apache.servicemix.bundles.zxing@default:default,org.apache.shiro.core@default:default,org.apache.shiro.ehcache@default:default,org.apache.shiro.web@default:default,org.apache.xmlbeans@default:default,org.dom4j@default:default,org.eclipse.equinox.cm@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.equinox.launcher@default:default,org.eclipse.equinox.simpleconfigurator@2:true,org.eclipse.jetty.client@default:default,org.eclipse.jetty.deploy@4:true,org.eclipse.jetty.http@4:true,org.eclipse.jetty.io@4:true,org.eclipse.jetty.jmx@4:true,org.eclipse.jetty.osgi.boot@3:true,org.eclipse.jetty.security@4:true,org.eclipse.jetty.server@4:true,org.eclipse.jetty.servlet@4:true,org.eclipse.jetty.util@4:true,org.eclipse.jetty.webapp@4:true,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.xml@4:true,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.hyperic.sigar@default:default,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,routeconverter@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="false"/>
<stringAttribute key="workspace_bundles" value="com.google.gwt.servlet@default:default,com.googlecode.java-diff-utils@default:default,com.sap.sailing.barbados.resultimport@4:true,com.sap.sailing.competitorimport@default:default,com.sap.sailing.dashboards.gwt@6:true,com.sap.sailing.datamining.provider@default:default,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@5:true,com.sap.sailing.declination@default:default,com.sap.sailing.domain.bravoadapter@5:true,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@5:true,com.sap.sailing.domain.expeditionadapter@5:true,com.sap.sailing.domain.igtimiadapter.gateway@5:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@4:true,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@4:true,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@4:true,com.sap.sailing.domain.swisstimingadapter@5:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@4:true,com.sap.sailing.domain.tractracadapter@5:true,com.sap.sailing.domain.windfinderadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@4:true,com.sap.sailing.expeditionconnector.common@default:default,com.sap.sailing.expeditionconnector.persistence@4:true,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@4:true,com.sap.sailing.geocoding@default:default,com.sap.sailing.grib@default:default,com.sap.sailing.gwt.ui@6:true,com.sap.sailing.kiworesultimport@4:true,com.sap.sailing.manage2sail.resultimport@4:true,com.sap.sailing.manage2sail@default:default,com.sap.sailing.monitoring@7:true,com.sap.sailing.news@4:true,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.polars.datamining.shared@default:default,com.sap.sailing.polars.datamining@5:true,com.sap.sailing.polars@5:true,com.sap.sailing.resultimport@4:true,com.sap.sailing.routeconverterjava11extension@default:false,com.sap.sailing.sailwave.resultimport@4:true,com.sap.sailing.server.gateway.serialization.shared.android@default:default,com.sap.sailing.server.gateway.serialization@default:default,com.sap.sailing.server.gateway@5:true,com.sap.sailing.server.interface@default:default,com.sap.sailing.server.trackfiles@default:default,com.sap.sailing.server@5:true,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@4:true,com.sap.sailing.www@5:true,com.sap.sailing.xmlexport@5:true,com.sap.sailing.xrr.resultimport@4:true,com.sap.sailing.xrr.schema@default:default,com.sap.sailing.xrr.structureimport@default:default,com.sap.sailing.yachtscoring.resultimport@4:true,com.sap.sse.common@default:default,com.sap.sse.datamining.annotations@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining.ui@default:default,com.sap.sse.datamining@default:default,com.sap.sse.filestorage@4:true,com.sap.sse.gwt.adminconsole@default:default,com.sap.sse.gwt@default:default,com.sap.sse.jersey.jaxbdependencyfragment@default:false,com.sap.sse.jettyextensions@default:false,com.sap.sse.mail@5:true,com.sap.sse.mongodb@default:default,com.sap.sse.operationaltransformation@default:default,com.sap.sse.replication.interfaces@default:default,com.sap.sse.replication@6:true,com.sap.sse.security.common@default:default,com.sap.sse.security.interface@default:default,com.sap.sse.security.persistence@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security@default:default,com.sap.sse.shared.android@default:default,com.sap.sse.threadmanager@default:default,com.sap.sse@default:default,com.tractrac.clientmodule@default:default,net.sf.marineapi@default:default,org.json.simple@default:default,org.moxieapps.gwt.highcharts@default:default,org.mp4parser.isoparser@default:default"/>
</launchConfiguration>
@@ -3,6 +3,8 @@ package com.sap.sse.gwt.server;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.RpcTokenException;
@@ -14,6 +16,8 @@ import com.google.gwt.user.server.rpc.SerializationPolicy;
import com.sap.sse.common.TimePoint;
public abstract class DelegatingProxiedRemoteServiceServlet extends ProxiedRemoteServiceServlet {
private static final Logger logger = Logger.getLogger(DelegatingProxiedRemoteServiceServlet.class.getName())
;
private static final long serialVersionUID = -5543378343472849437L;
/**
@@ -73,6 +77,7 @@ public abstract class DelegatingProxiedRemoteServiceServlet extends ProxiedRemot
} catch (InvocationTargetException e) {
// Try to encode the caught exception
Throwable cause = e.getCause();
logger.log(Level.SEVERE, "Uncaught exception, forwarded to client", cause);
responsePayload = RPC.encodeResponseForFailure(serviceMethod, cause, serializationPolicy, flags);
}
return responsePayload;
@@ -34,7 +34,7 @@ userDetails=Detalles de usuario
deleteUser=Borrar usuario
deleteUserQuestion=¿Desea borrar el usuario?
doYouReallyWantToDeleteUser=¿Está seguro de que desea borrar el usuario {0}?
doYouReallyWantToDeleteNUsers=Do you really want to delete {0} users?
doYouReallyWantToDeleteNUsers=¿Está seguro de que desea borrar los usuarios {0}?
account={0}-Cuenta
save=Grabar
remove=Eliminar
@@ -108,85 +108,85 @@ settingsRemovedError=No se han podido restablecer las parametrizaciones por defe
showMoreInfoLogin=Regístrese para acceder a más funciones
dismiss=Más tarde
moreInfo=Más info
editACL=Edit ACL
errorEditingACL=Error editing access control list (ACL).
editAnACL=Edit an access control list (ACL)
createUserGroup=Create user group
removeUserGroup=Remove user group
youHaveToSelectAUserGroup=You have to select a user group.
doYouReallyWantToRemoveUserGroup=Do you really want to remove user group {0}?
couldNotDeleteUserGroup=Could not delete user group.
filterUserGroups=Filter user groups...
editACL=Editar ACL
errorEditingACL=Error al editar la lista de control de accesos (ACL).
editAnACL=Editar una lista de control de accesos (ACL).
createUserGroup=Crear grupo de usuarios
removeUserGroup=Eliminar grupo de usuarios
youHaveToSelectAUserGroup=Debe seleccionar un grupo de usuarios.
doYouReallyWantToRemoveUserGroup=¿Está seguro de que desea eliminar el grupo de usuarios {0}?
couldNotDeleteUserGroup=No se ha podido borrar el grupo de usuarios.
filterUserGroups=Filtrar grupos de usuarios...
id=ID
displayName=Display Name
userGroups=User Groups
errorTryingToLoadRoles=Error trying to load roles: {0}
filterRoles=Filter roles
actions=Actions
actionEdit=Edit
actionRemove=Remove
actionChangeOwnership=Change ownership
errorUpdatingOwnership=Error updating ownership of object {0}
doYouReallyWantToRemoveRole=Do you really want to remove role(s) "{0}"?
errorTryingToDeleteRole=Error trying to delete role "{0}": {1}
pleaseEnterARoleName=Please enter a role name
editRoles=Edit Roles
otherRoleWithNameAlreadyExists=Another role with name "{0}" already exists.
errorCreatingRole=Error creating role "{0}": {1}
errorEditingRoles=Error editing role "{0}": {1}
usersInUserGroup=Users in user group
allUsers=All users
couldNotAddUserToUserGroup=Could not add user {0} to user group {1}: {2}
couldNotRemoveUserFromUserGroup=Could not remove user {0} from user group {1}: {2}
enterUserGroupName=Enter user group name
defaultTenant=User group to use for object creation
pagerStateInfo={0,number,#,###}-{1,number,#,###} of {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} of over {2,number,#,###}
yes=Yes
displayName=Visualizar nombre
userGroups=Grupos de usuarios
errorTryingToLoadRoles=Error al intentar cargar roles: {0}
filterRoles=Filtrar roles
actions=Acciones
actionEdit=Editar
actionRemove=Eliminar
actionChangeOwnership=Modificar propiedad
errorUpdatingOwnership=Error al actualizar la propiedad del objeto {0}
doYouReallyWantToRemoveRole=¿Está seguro de que desea eliminar el rol o los roles "{0}"?
errorTryingToDeleteRole=Error al intentar eliminar el rol "{0}": {1}
pleaseEnterARoleName=Indique un nombre de rol
editRoles=Editar roles
otherRoleWithNameAlreadyExists=Ya existe otro rol con el nombre "{0}".
errorCreatingRole=Error al crear el rol "{0}": {1}
errorEditingRoles=Error al editar el rol "{0}": {1}
usersInUserGroup=Usuarios en el grupo de usuarios
allUsers=Todos los usuarios
couldNotAddUserToUserGroup=No se ha podido añadir el usuario {0} al grupo de usuarios {1}: {2}
couldNotRemoveUserFromUserGroup=No se ha podido eliminar el usuario {0} del grupo de usuarios {1}: {2}
enterUserGroupName=Indicar nombre de grupo de usuarios
defaultTenant=Grupo de usuarios que debe utilizarse para la creación de objetos
pagerStateInfo={0,number,#,###}-{1,number,#,###} de {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} de más de {2,number,#,###}
yes=Sí
no=No
editUser=Edit User
validated=Validated
groups=Groups
group=Group
errorDeletingUser=Se ha producido un error al borrar el usuario {0}: {1}
doYouReallyWantToRemoveUser=Really remove user {0}?
errorTryingToUpdateUser=Error trying to update user {0}: {1}
ownership=Ownership
editObjectOwnership=Edit object ownership
errorObtainingUser=Error obtaining user: {0}
errorObtainingUserGroup=Error obtaining user group: {0}
pleaseWaitUntilUsernameIsResolved=Please wait until user name is resolved
pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is resolved
userNotFound=User {0} not found
usergroupNotFound=User group {0} not found
actionChangeACL=Change ACL
editACLForObject=Edit ACL for ''{0}''
editUser=Editar usuario
validated=Validado
groups=Grupos
group=Grupo
errorDeletingUser=Error al borrar el usuario {0}: {1}
doYouReallyWantToRemoveUser=¿Está seguro de que desea eliminar el usuario {0}?
errorTryingToUpdateUser=Error al intentar actualizar el usuario {0}: {1}
ownership=Propiedad
editObjectOwnership=Editar propiedad de objeto
errorObtainingUser=Error al obtener el usuario: {0}
errorObtainingUserGroup=Error al obtener el grupo de usuarios: {0}
pleaseWaitUntilUsernameIsResolved=Espere hasta que el nombre del usuario se haya resuelto
pleaseWaitUntilUserGroupNameIsResolved=Espere hasta que el nombre del grupo de usuarios se haya resuelto
userNotFound=El usuario {0} no existe
usergroupNotFound=El grupo de usuarios {0} no existe
actionChangeACL=Modificar ACL
editACLForObject=Editar ACL para ''{0}''
acl=ACL
errorUpdatingAcl=Error updating ACL: {0}.
allowedActionName=Allowed action name
deniedActionName=Denied action name
errorMessageUserGroupNameNotFound=Did not find user group by name {0}.
successMessageAddedUserGroup=Added user group {0}.
successMessageRemovedUserGroup=Removed user group {0}.
allowedActions=Allowed Actions
deniedActions=Denied Actions
migrateGroupOwner=Migrate group owner for hierarchy
errorDeletingUserGroup=Error deleting user group {0}: {1}
enterAtLeastOneOwner=Please enter at least one owner
removeRole=Remove role
addRole=Add role
couldNotAddRoleToGroup=Role {0} could not be added to group {1}.
roleName=Role Name
enabledForAllUsers=Enabled for all users
couldNotDeleteRole=Could not delete role {0}.
couldNotLoadRoles=Could not load roles.
enterUsername=Enter user name
addUser=Add user
couldNotLoadUsers=Could not load users.
couldNotRemoveRoleFromUser=Could not remove role ''{1}'' from user ''{0}''.
couldNotRemovePermissionFromUser=Could not remove permission ''{1}'' from user ''{0}''.
filterPermission=Filter permission
permission=Permission
errorUpdatingAcl=Error al actualizar ACL: {0}.
allowedActionName=Nombre de acción permitido
deniedActionName=Nombre de acción denegado
errorMessageUserGroupNameNotFound=No se ha encontrado el grupo de usuarios por nombre {0}.
successMessageAddedUserGroup=Grupo de usuarios añadido {0}.
successMessageRemovedUserGroup=Grupo de usuarios eliminado {0}.
allowedActions=Acciones permitidas
deniedActions=Acciones denegadas
migrateGroupOwner=Migrar propietario de grupo para jerarquía
errorDeletingUserGroup=Error al borrar el grupo de usuarios {0}: {1}
enterAtLeastOneOwner=Indique como mínimo un propietario
removeRole=Eliminar rol
addRole=Añadir rol
couldNotAddRoleToGroup=El rol {0} no se ha podido añadir al grupo {1}.
roleName=Nombre de rol
enabledForAllUsers=Activado para todos los usuarios
couldNotDeleteRole=No se ha podido borrar el rol {0}.
couldNotLoadRoles=No se han podido cargar los roles.
enterUsername=Indicar nombre de usuario
addUser=Añadir usuario
couldNotLoadUsers=No se han podido cargar los usuarios.
couldNotRemoveRoleFromUser=No se ha podido eliminar el rol ''{1}'' del usuario ''{0}''.
couldNotRemovePermissionFromUser=No se ha podido eliminar el permiso ''{1}'' del usuario ''{0}''.
filterPermission=Autorización de filtro
permission=Autorización
nullUserGroup=<Anonymous UserGroup>
editRolesAndPermissionsForUser=Edit roles and permissions for user {0}
permissionType:Permission Type
editRolesAndPermissionsForUser=Editar roles y autorizaciones para el usuario {0}
permissionType:Tipo de autorización
@@ -34,7 +34,7 @@ userDetails=Détails utilisateur
deleteUser=Supprimer utilisateur
deleteUserQuestion=Supprimer l''utilisateur ?
doYouReallyWantToDeleteUser=Souhaitez-vous vraiment supprimer l''utilisateur {0} ?
doYouReallyWantToDeleteNUsers=Do you really want to delete {0} users?
doYouReallyWantToDeleteNUsers=Voulez-vous vraiment supprimer {0} utilisateur(s) ?
account=Compte {0}
save=Enregistrer
remove=Supprimer
@@ -108,85 +108,85 @@ settingsRemovedError=Impossible de restaurer les options par défaut
showMoreInfoLogin=Connectez-vous pour accéder à davantage de fonctionnalités
dismiss=Plus tard
moreInfo=Plus d''infos
editACL=Edit ACL
errorEditingACL=Error editing access control list (ACL).
editAnACL=Edit an access control list (ACL)
createUserGroup=Create user group
removeUserGroup=Remove user group
youHaveToSelectAUserGroup=You have to select a user group.
doYouReallyWantToRemoveUserGroup=Do you really want to remove user group {0}?
couldNotDeleteUserGroup=Could not delete user group.
filterUserGroups=Filter user groups...
editACL=Modifier la liste de contrôle d''accès (ACL)
errorEditingACL=Erreur lors de la modification de la liste de contrôle d''accès (ACL)
editAnACL=Modifier une liste de contrôle d''accès (ACL)
createUserGroup=Créer groupe d''utilisateurs
removeUserGroup=Supprimer groupe d''utilisateurs
youHaveToSelectAUserGroup=Vous devez sélectionner un groupe d''utilisateurs.
doYouReallyWantToRemoveUserGroup=Souhaitez-vous vraiment supprimer le groupe d''utilisateurs {0} ?
couldNotDeleteUserGroup=Impossible de supprimer le groupe d''utilisateurs
filterUserGroups=Filtrer les groupes d''utilisateurs...
id=ID
displayName=Display Name
userGroups=User Groups
errorTryingToLoadRoles=Error trying to load roles: {0}
filterRoles=Filter roles
displayName=Nom d''affichage
userGroups=Groupes d''utilisateurs
errorTryingToLoadRoles=Erreur lors du chargement de rôles : {0}
filterRoles=Filtrer rôles
actions=Actions
actionEdit=Edit
actionRemove=Remove
actionChangeOwnership=Change ownership
errorUpdatingOwnership=Error updating ownership of object {0}
doYouReallyWantToRemoveRole=Do you really want to remove role(s) "{0}"?
errorTryingToDeleteRole=Error trying to delete role "{0}": {1}
pleaseEnterARoleName=Please enter a role name
editRoles=Edit Roles
otherRoleWithNameAlreadyExists=Another role with name "{0}" already exists.
errorCreatingRole=Error creating role "{0}": {1}
errorEditingRoles=Error editing role "{0}": {1}
usersInUserGroup=Users in user group
allUsers=All users
couldNotAddUserToUserGroup=Could not add user {0} to user group {1}: {2}
couldNotRemoveUserFromUserGroup=Could not remove user {0} from user group {1}: {2}
enterUserGroupName=Enter user group name
defaultTenant=User group to use for object creation
pagerStateInfo={0,number,#,###}-{1,number,#,###} of {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} of over {2,number,#,###}
yes=Yes
no=No
editUser=Edit User
validated=Validated
groups=Groups
group=Group
errorDeletingUser=Une erreur s''est produite lors de la suppression de l''utilisateur {0}: {1}
doYouReallyWantToRemoveUser=Really remove user {0}?
errorTryingToUpdateUser=Error trying to update user {0}: {1}
ownership=Ownership
editObjectOwnership=Edit object ownership
errorObtainingUser=Error obtaining user: {0}
errorObtainingUserGroup=Error obtaining user group: {0}
pleaseWaitUntilUsernameIsResolved=Please wait until user name is resolved
pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is resolved
userNotFound=User {0} not found
usergroupNotFound=User group {0} not found
actionChangeACL=Change ACL
editACLForObject=Edit ACL for ''{0}''
actionEdit=Modifier
actionRemove=Supprimer
actionChangeOwnership=Modifier détention
errorUpdatingOwnership=Erreur lors de la mise à jour de la détention de l''objet {0}.
doYouReallyWantToRemoveRole=Souhaitez-vous vraiment supprimer le(s) rôle(s) "{0}" ?
errorTryingToDeleteRole=Erreur lors de la suppression du rôle"{0}" : {1}
pleaseEnterARoleName=Saisissez un nom de rôle.
editRoles=Modifier rôles
otherRoleWithNameAlreadyExists=Un rôle du nom "{0}" existe déjà.
errorCreatingRole=Erreur lors de la création du rôle "{0}" : {1}
errorEditingRoles=Erreur lors de la modification du rôle "{0}" : {1}
usersInUserGroup=Utilisateurs dans le groupe d''utilisateurs
allUsers=Tous les utilisateurs
couldNotAddUserToUserGroup=Impossible d''ajouter l''utilisateur {0} au groupe d''utilisateurs {1} : {2}
couldNotRemoveUserFromUserGroup=Impossible de supprimer l''utilisateur {0} du groupe d''utilisateurs {1} : {2}
enterUserGroupName=Saisissez le nom du groupe d''utilisateurs.
defaultTenant=Groupe d''utilisateurs à utiliser pour la création d''objet
pagerStateInfo={0,number,#,###}-{1,number,#,###} sur {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} sur plus de {2,number,#,###}
yes=Oui
no=Non
editUser=Modifier utilisateur
validated=Validé
groups=Groupes
group=Groupe
errorDeletingUser=Erreur lors de la suppression de l''utilisateur {0} : {1}
doYouReallyWantToRemoveUser=Supprimer vraiment l''utilisateur {0} ?
errorTryingToUpdateUser=Erreur lors de la mise à jour de l''utilisateur {0} : {1}
ownership=Détention
editObjectOwnership=Modifier la détention de l''objet
errorObtainingUser=Erreur lors de l''accès à l''utilisateur : {0}
errorObtainingUserGroup=Erreur lors de l''accès au groupe d''utilisateurs : {0}
pleaseWaitUntilUsernameIsResolved=Veuillez patienter jusqu''à la résolution du nom d''utilisateur.
pleaseWaitUntilUserGroupNameIsResolved=Veuillez patienter jusqu''à la résolution du nom du groupe d''utilisateurs.
userNotFound=Utilisateur {0} introuvable
usergroupNotFound=Groupe d''utilisateurs {0} introuvable
actionChangeACL=Modifier l''ACL
editACLForObject=Modifier l''ACL en ''{0}''
acl=ACL
errorUpdatingAcl=Error updating ACL: {0}.
allowedActionName=Allowed action name
deniedActionName=Denied action name
errorMessageUserGroupNameNotFound=Did not find user group by name {0}.
successMessageAddedUserGroup=Added user group {0}.
successMessageRemovedUserGroup=Removed user group {0}.
allowedActions=Allowed Actions
deniedActions=Denied Actions
migrateGroupOwner=Migrate group owner for hierarchy
errorDeletingUserGroup=Error deleting user group {0}: {1}
enterAtLeastOneOwner=Please enter at least one owner
removeRole=Remove role
addRole=Add role
couldNotAddRoleToGroup=Role {0} could not be added to group {1}.
roleName=Role Name
enabledForAllUsers=Enabled for all users
couldNotDeleteRole=Could not delete role {0}.
couldNotLoadRoles=Could not load roles.
enterUsername=Enter user name
addUser=Add user
couldNotLoadUsers=Could not load users.
couldNotRemoveRoleFromUser=Could not remove role ''{1}'' from user ''{0}''.
couldNotRemovePermissionFromUser=Could not remove permission ''{1}'' from user ''{0}''.
filterPermission=Filter permission
permission=Permission
errorUpdatingAcl=Erreur lors de la mise à jour de l''ACL : {0}
allowedActionName=Nom de l''action autorisée
deniedActionName=Nom de l''action refusée
errorMessageUserGroupNameNotFound=La recherche du groupe d''utilisateurs par le nom {0} a échoué.
successMessageAddedUserGroup=Groupe d''utilisateurs {0} ajouté
successMessageRemovedUserGroup=Groupe d''utilisateurs {0} supprimé
allowedActions=Actions autorisées
deniedActions=Actions refusées
migrateGroupOwner=Migrer détenteur de groupe pour hiérarchie
errorDeletingUserGroup=Erreur lors de la suppression du groupe d''utilisateurs {0} : {1}
enterAtLeastOneOwner=Veuillez saisir au moins un détenteur.
removeRole=Supprimer rôle
addRole=Ajouter rôle
couldNotAddRoleToGroup=Le rôle {0} n''a pas pu être ajouté au groupe {1}.
roleName=Nom du rôle
enabledForAllUsers=Activé pour tous les utilisateurs
couldNotDeleteRole=Impossible de supprimer le rôle {0}
couldNotLoadRoles=Impossible de charger les rôles
enterUsername=Saisissez le nom d''utilisateur.
addUser=Ajouter utilisateur
couldNotLoadUsers=Impossible de charger les utilisateurs
couldNotRemoveRoleFromUser=Impossible de supprimer le rôle ''{1}'' de l''utilisateur ''{0}''.
couldNotRemovePermissionFromUser=Impossible de supprimer l''autorisation ''{1}'' de l''utilisateur ''{0}''.
filterPermission=Filtrer autorisations
permission=Autorisation
nullUserGroup=<Anonymous UserGroup>
editRolesAndPermissionsForUser=Edit roles and permissions for user {0}
permissionType:Permission Type
editRolesAndPermissionsForUser=Modifier les rôles et autorisations pour l''utilisateur {0}
permissionType:Type d''autorisation
@@ -34,7 +34,7 @@ userDetails=ユーザ詳細
deleteUser=ユーザ削除
deleteUserQuestion=ユーザを削除しますか
doYouReallyWantToDeleteUser=ユーザ {0} を削除しますか
doYouReallyWantToDeleteNUsers=Do you really want to delete {0} users?
doYouReallyWantToDeleteNUsers={0} ユーザを削除しますか
account={0} アカウント
save=保存
remove=削除
@@ -108,84 +108,85 @@ settingsRemovedError=デフォルト設定を復元できませんでした
showMoreInfoLogin=サインインして追加機能へのアクセス権限を取得してください
dismiss=後で
moreInfo=追加情報
editACL=Edit ACL
errorEditingACL=Error editing access control list (ACL).
editAnACL=Edit an access control list (ACL)
createUserGroup=Create user group
removeUserGroup=Remove user group
youHaveToSelectAUserGroup=You have to select a user group.
doYouReallyWantToRemoveUserGroup=Do you really want to remove user group {0}?
couldNotDeleteUserGroup=Could not delete user group.
filterUserGroups=Filter user groups...
editACL=ACL 編集
errorEditingACL=アクセスコントロールリスト (ACL) の編集でエラーが発生しました。
editAnACL=アクセスコントロールリスト (ACL) を編集
createUserGroup=ユーザグループを作成
removeUserGroup=ユーザグループを削除
youHaveToSelectAUserGroup=ユーザグループを選択する必要があります。
doYouReallyWantToRemoveUserGroup=ユーザグループ {0} を削除しますか。
couldNotDeleteUserGroup=ユーザグループを削除できませんでした。
filterUserGroups=ユーザグループのフィルタリング...
id=ID
displayName=Display Name
userGroups=User Groups
errorTryingToLoadRoles=Error trying to load roles: {0}
filterRoles=Filter roles
actions=Actions
actionEdit=Edit
actionRemove=Remove
actionChangeOwnership=Change ownership
errorUpdatingOwnership=Error updating ownership of object {0}
doYouReallyWantToRemoveRole=Do you really want to remove role(s) "{0}"?
errorTryingToDeleteRole=Error trying to delete role "{0}": {1}
pleaseEnterARoleName=Please enter a role name
editRoles=Edit Roles
otherRoleWithNameAlreadyExists=Another role with name "{0}" already exists.
errorCreatingRole=Error creating role "{0}": {1}
errorEditingRoles=Error editing role "{0}": {1}
usersInUserGroup=Users in user group
allUsers=All users
couldNotAddUserToUserGroup=Could not add user {0} to user group {1}: {2}
couldNotRemoveUserFromUserGroup=Could not remove user {0} from user group {1}: {2}
enterUserGroupName=Enter user group name
defaultTenant=User group to use for object creation
pagerStateInfo={0,number,#,###}-{1,number,#,###} of {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} of over {2,number,#,###}
yes=Yes
no=No
editUser=Edit User
validated=Validated
groups=Groups
group=Group
doYouReallyWantToRemoveUser=Really remove user {0}?
errorTryingToUpdateUser=Error trying to update user {0}: {1}
ownership=Ownership
editObjectOwnership=Edit object ownership
errorObtainingUser=Error obtaining user: {0}
errorObtainingUserGroup=Error obtaining user group: {0}
pleaseWaitUntilUsernameIsResolved=Please wait until user name is resolved
pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is resolved
userNotFound=User {0} not found
usergroupNotFound=User group {0} not found
actionChangeACL=Change ACL
editACLForObject=Edit ACL for ''{0}''
displayName=表示名
userGroups=ユーザグループ
errorTryingToLoadRoles=ロールをロードしようとしてエラーが発生: {0}
filterRoles=ロールのフィルタリング
actions=アクション
actionEdit=編集
actionRemove=削除
actionChangeOwnership=オーナーシップ変更
errorUpdatingOwnership=オブジェクト {0} のオーナーシップ更新でエラーが発生しました
doYouReallyWantToRemoveRole=ロール "{0}" を削除しますか
errorTryingToDeleteRole=ロール "{0}" を削除しようとしてエラーが発生: {1}
pleaseEnterARoleName=ロール名を入力してください
editRoles=ロール編集
otherRoleWithNameAlreadyExists="{0}" という名前の別のロールはすでに存在しています。
errorCreatingRole=ロール "{0}" の作成でエラー発生: {1}
errorEditingRoles=ロール "{0}" の編集でエラー発生: {1}
usersInUserGroup=ユーザグループにあるユーザ
allUsers=すべてのユーザ
couldNotAddUserToUserGroup=ユーザ {0} をユーザグループ {1} に追加できませんでした: {2}
couldNotRemoveUserFromUserGroup=ユーザ {0} をユーザグループ {1} から削除できませんでした: {2}
enterUserGroupName=ユーザグループ名を入力
defaultTenant=オブジェクト作成に使用するユーザグループ
pagerStateInfo={2,number,#,###} の {0,number,#,###} ~ {1,number,#,###}
pagerStateInfo[false]={2,number,#,###} 上の {0,number,#,###} ~ {1,number,#,###}
yes=はい
no=いいえ
editUser=ユーザ編集
validated=チェック済
groups=グループ
group=グループ
errorDeletingUser=ユーザ {0} の削除でエラー発生: {1}
doYouReallyWantToRemoveUser=ユーザ {0} を削除しますか
errorTryingToUpdateUser=ユーザ {0} を更新しようとしてエラーが発生: {1}
ownership=オーナーシップ
editObjectOwnership=オブジェクトオーナーシップ編集
errorObtainingUser=ユーザの取得でエラーが発生: {0}
errorObtainingUserGroup=ユーザグループの取得でエラーが発生: {0}
pleaseWaitUntilUsernameIsResolved=ユーザ名が削除されるまで待ってください
pleaseWaitUntilUserGroupNameIsResolved=ユーザグループ名が解決されるまで待ってください
userNotFound=ユーザ {0} は見つかりませんでした
usergroupNotFound=ユーザグループ {0} は見つかりませんでした
actionChangeACL=ACL 変更
editACLForObject=''{0}'' の ACL を編集
acl=ACL
errorUpdatingAcl=Error updating ACL: {0}.
allowedActionName=Allowed action name
deniedActionName=Denied action name
errorMessageUserGroupNameNotFound=Did not find user group by name {0}.
successMessageAddedUserGroup=Added user group {0}.
successMessageRemovedUserGroup=Removed user group {0}.
allowedActions=Allowed Actions
deniedActions=Denied Actions
migrateGroupOwner=Migrate group owner for hierarchy
errorDeletingUserGroup=Error deleting user group {0}: {1}
enterAtLeastOneOwner=Please enter at least one owner
removeRole=Remove role
addRole=Add role
couldNotAddRoleToGroup=Role {0} could not be added to group {1}.
roleName=Role Name
enabledForAllUsers=Enabled for all users
couldNotDeleteRole=Could not delete role {0}.
couldNotLoadRoles=Could not load roles.
enterUsername=Enter user name
addUser=Add user
couldNotLoadUsers=Could not load users.
couldNotRemoveRoleFromUser=Could not remove role ''{1}'' from user ''{0}''.
couldNotRemovePermissionFromUser=Could not remove permission ''{1}'' from user ''{0}''.
filterPermission=Filter permission
permission=Permission
errorUpdatingAcl=ACL の更新でエラー発生: {0}
allowedActionName=許可されたアクション名
deniedActionName=拒否されたアクション名
errorMessageUserGroupNameNotFound={0} という名前でユーザグループが見つかりませんでした。
successMessageAddedUserGroup=ユーザグループ {0} が追加されました。
successMessageRemovedUserGroup=ユーザグループ {0} が削除されました。
allowedActions=許可されたアクション
deniedActions=拒否されたアクション
migrateGroupOwner=階層のグループオーナーを移行
errorDeletingUserGroup=ユーザグループ {0} の削除でエラーが発生: {1}
enterAtLeastOneOwner=少なくとも 1 名のオーナーを入力してください
removeRole=ロール削除
addRole=ロール追加
couldNotAddRoleToGroup=ロール {0} をグループ {1} に追加できませんでした。
roleName=ロール名
enabledForAllUsers=すべてのユーザに対して有効化されました
couldNotDeleteRole=ロール {0} を削除できませんでした。
couldNotLoadRoles=ロールをロードできませんでした。
enterUsername=ユーザ名を入力してください
addUser=ユーザ追加
couldNotLoadUsers=ユーザをロードできませんでした。
couldNotRemoveRoleFromUser=ロール ''{1}'' をユーザ ''{0}'' から削除できませんでした。
couldNotRemovePermissionFromUser=権限 ''{1}'' をユーザ ''{0}'' から削除できませんでした。
filterPermission=権限のフィルタリング
permission=権限
nullUserGroup=<Anonymous UserGroup>
editRolesAndPermissionsForUser=Edit roles and permissions for user {0}
permissionType:Permission Type
editRolesAndPermissionsForUser=ユーザ {0} のロールと権限を編集
permissionType:権限タイプ
@@ -34,7 +34,7 @@ userDetails=Detalhes do usuário
deleteUser=Eliminar usuário
deleteUserQuestion=Eliminar usuário?
doYouReallyWantToDeleteUser=Eliminar o usuário {0}?
doYouReallyWantToDeleteNUsers=Do you really want to delete {0} users?
doYouReallyWantToDeleteNUsers=Eliminar {0} usuários?
account=Conta {0}
save=Gravar
remove=Eliminar
@@ -108,85 +108,85 @@ settingsRemovedError=Não foi possível restaurar configurações padrão
showMoreInfoLogin=Efetue o logon para obter acesso a mais funcionalidades
dismiss=Mais tarde
moreInfo=Mais informação
editACL=Edit ACL
errorEditingACL=Error editing access control list (ACL).
editAnACL=Edit an access control list (ACL)
createUserGroup=Create user group
removeUserGroup=Remove user group
youHaveToSelectAUserGroup=You have to select a user group.
doYouReallyWantToRemoveUserGroup=Do you really want to remove user group {0}?
couldNotDeleteUserGroup=Could not delete user group.
filterUserGroups=Filter user groups...
editACL=Processar ACL
errorEditingACL=Erro ao processar lista de controle de acesso (ACL).
editAnACL=Processar uma lista de controle de acesso (ACL)
createUserGroup=Criar grupo de usuários
removeUserGroup=Remover grupo de usuários
youHaveToSelectAUserGroup=Você precisa selecionar um grupo de usuários.
doYouReallyWantToRemoveUserGroup=Remover o grupo de usuários {0}?
couldNotDeleteUserGroup=Não foi possível eliminar grupo de usuários.
filterUserGroups=Filtrar grupos de usuários...
id=ID
displayName=Display Name
userGroups=User Groups
errorTryingToLoadRoles=Error trying to load roles: {0}
filterRoles=Filter roles
actions=Actions
actionEdit=Edit
actionRemove=Remove
actionChangeOwnership=Change ownership
errorUpdatingOwnership=Error updating ownership of object {0}
doYouReallyWantToRemoveRole=Do you really want to remove role(s) "{0}"?
errorTryingToDeleteRole=Error trying to delete role "{0}": {1}
pleaseEnterARoleName=Please enter a role name
editRoles=Edit Roles
otherRoleWithNameAlreadyExists=Another role with name "{0}" already exists.
errorCreatingRole=Error creating role "{0}": {1}
errorEditingRoles=Error editing role "{0}": {1}
usersInUserGroup=Users in user group
allUsers=All users
couldNotAddUserToUserGroup=Could not add user {0} to user group {1}: {2}
couldNotRemoveUserFromUserGroup=Could not remove user {0} from user group {1}: {2}
enterUserGroupName=Enter user group name
defaultTenant=User group to use for object creation
pagerStateInfo={0,number,#,###}-{1,number,#,###} of {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} of over {2,number,#,###}
yes=Yes
no=No
editUser=Edit User
validated=Validated
groups=Groups
group=Group
errorDeletingUser=Ocorreu um erro ao eliminar o usuário {0}: {1}
doYouReallyWantToRemoveUser=Really remove user {0}?
errorTryingToUpdateUser=Error trying to update user {0}: {1}
ownership=Ownership
editObjectOwnership=Edit object ownership
errorObtainingUser=Error obtaining user: {0}
errorObtainingUserGroup=Error obtaining user group: {0}
pleaseWaitUntilUsernameIsResolved=Please wait until user name is resolved
pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is resolved
userNotFound=User {0} not found
usergroupNotFound=User group {0} not found
actionChangeACL=Change ACL
editACLForObject=Edit ACL for ''{0}''
displayName=Nome de exibição
userGroups=Grupos de usuários
errorTryingToLoadRoles=Erro ao tentar carregar funções: {0}
filterRoles=Filtrar funções
actions=Ações
actionEdit=Processar
actionRemove=Remover
actionChangeOwnership=Modificar propriedade
errorUpdatingOwnership=Erro ao atualizar propriedade de objeto {0}
doYouReallyWantToRemoveRole=Remover funções "{0}"?
errorTryingToDeleteRole=Erro ao tentar eliminar função "{0}": {1}
pleaseEnterARoleName=Inserir um nome de função
editRoles=Processar funções
otherRoleWithNameAlreadyExists=Já existe outra função com o nome "{0}".
errorCreatingRole=Erro ao criar função "{0}": {1}
errorEditingRoles=Erro ao processar função "{0}": {1}
usersInUserGroup=Usuários no grupo de usuários
allUsers=Todos os usuários
couldNotAddUserToUserGroup=Não foi possível adicionar o usuário {0} ao grupo de usuários {1}: {2}
couldNotRemoveUserFromUserGroup=Não foi possível remover o usuário {0} do grupo de usuários {1}: {2}
enterUserGroupName=Inserir nome do grupo de usuários
defaultTenant=Grupo de usuários para utilizar para criação de objeto
pagerStateInfo={0,number,#,###}-{1,number,#,###} de {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} de mais de {2,number,#,###}
yes=Sim
no=Não
editUser=Processar usuário
validated=Validado
groups=Grupos
group=Grupo
errorDeletingUser=Erro ao eliminar usuário {0}: {1}
doYouReallyWantToRemoveUser=Remover usuário {0}?
errorTryingToUpdateUser=Erro ao tentar atualizar usuário {0}: {1}
ownership=Propriedade
editObjectOwnership=Processar propriedade de objeto
errorObtainingUser=Erro ao obter usuário: {0}
errorObtainingUserGroup=Erro ao obter grupo de usuários: {0}
pleaseWaitUntilUsernameIsResolved=Aguardar até nome de usuário estar resolvido
pleaseWaitUntilUserGroupNameIsResolved=Aguardar até nome de grupo de usuários estar resolvido
userNotFound=Usuário {0} não encontrado
usergroupNotFound=Grupo de usuários {0} não encontrado
actionChangeACL=Modificar ACL
editACLForObject=Processar ACL para ''{0}''
acl=ACL
errorUpdatingAcl=Error updating ACL: {0}.
allowedActionName=Allowed action name
deniedActionName=Denied action name
errorMessageUserGroupNameNotFound=Did not find user group by name {0}.
successMessageAddedUserGroup=Added user group {0}.
successMessageRemovedUserGroup=Removed user group {0}.
allowedActions=Allowed Actions
deniedActions=Denied Actions
migrateGroupOwner=Migrate group owner for hierarchy
errorDeletingUserGroup=Error deleting user group {0}: {1}
enterAtLeastOneOwner=Please enter at least one owner
removeRole=Remove role
addRole=Add role
couldNotAddRoleToGroup=Role {0} could not be added to group {1}.
roleName=Role Name
enabledForAllUsers=Enabled for all users
couldNotDeleteRole=Could not delete role {0}.
couldNotLoadRoles=Could not load roles.
enterUsername=Enter user name
addUser=Add user
couldNotLoadUsers=Could not load users.
couldNotRemoveRoleFromUser=Could not remove role ''{1}'' from user ''{0}''.
couldNotRemovePermissionFromUser=Could not remove permission ''{1}'' from user ''{0}''.
filterPermission=Filter permission
permission=Permission
errorUpdatingAcl=Erro ao atualizar ACL: {0}.
allowedActionName=Nome de ação permitido
deniedActionName=Nome de ação recusado
errorMessageUserGroupNameNotFound=Grupo de usuários não encontrado por nome {0}.
successMessageAddedUserGroup=Grupo de usuários adicionado {0}.
successMessageRemovedUserGroup=Grupo de usuários removido {0}.
allowedActions=Ações permitidas
deniedActions=Ações recusadas
migrateGroupOwner=Migrar proprietário do objeto para hierarquia
errorDeletingUserGroup=Erro ao eliminar grupo de usuários {0}: {1}
enterAtLeastOneOwner=Inserir pelo menos um proprietário
removeRole=Remover função
addRole=Adicionar função
couldNotAddRoleToGroup=Não foi possível adicionar função {0} ao grupo {1}.
roleName=Nome da função
enabledForAllUsers=Ativado para todos os usuários
couldNotDeleteRole=Não foi possível eliminar função {0}.
couldNotLoadRoles=Não foi possível carregar funções.
enterUsername=Inserir nome do usuário
addUser=Adicionar usuário
couldNotLoadUsers=Não foi possível carregar usuários.
couldNotRemoveRoleFromUser=Não foi possível remover função ''{1}'' de usuário ''{0}''.
couldNotRemovePermissionFromUser=Não foi possível remover autorização ''{1}'' do usuário ''{0}''.
filterPermission=Filtrar autorização
permission=Autorização
nullUserGroup=<Anonymous UserGroup>
editRolesAndPermissionsForUser=Edit roles and permissions for user {0}
permissionType:Permission Type
editRolesAndPermissionsForUser=Processar funções e autorizações para usuário {0}
permissionType:Tipo de autorização
@@ -34,7 +34,7 @@ userDetails=Данные пользователя
deleteUser=Удалить пользователя
deleteUserQuestion=Удалить пользователя?
doYouReallyWantToDeleteUser=Действительно удалить пользователя {0}?
doYouReallyWantToDeleteNUsers=Do you really want to delete {0} users?
doYouReallyWantToDeleteNUsers=Удалить {0} пользователей?
account={0}-учетная запись
save=Сохранить
remove=Удалить
@@ -108,85 +108,85 @@ settingsRemovedError=Не удалось восстановить настрой
showMoreInfoLogin=Выполните вход, чтобы получить доступ к дополнительным функциям
dismiss=Позже
moreInfo=Дополнительная информация
editACL=Edit ACL
errorEditingACL=Error editing access control list (ACL).
editAnACL=Edit an access control list (ACL)
createUserGroup=Create user group
removeUserGroup=Remove user group
youHaveToSelectAUserGroup=You have to select a user group.
doYouReallyWantToRemoveUserGroup=Do you really want to remove user group {0}?
couldNotDeleteUserGroup=Could not delete user group.
filterUserGroups=Filter user groups...
id=ID
displayName=Display Name
userGroups=User Groups
errorTryingToLoadRoles=Error trying to load roles: {0}
filterRoles=Filter roles
actions=Actions
actionEdit=Edit
actionRemove=Remove
actionChangeOwnership=Change ownership
errorUpdatingOwnership=Error updating ownership of object {0}
doYouReallyWantToRemoveRole=Do you really want to remove role(s) "{0}"?
errorTryingToDeleteRole=Error trying to delete role "{0}": {1}
pleaseEnterARoleName=Please enter a role name
editRoles=Edit Roles
otherRoleWithNameAlreadyExists=Another role with name "{0}" already exists.
errorCreatingRole=Error creating role "{0}": {1}
errorEditingRoles=Error editing role "{0}": {1}
usersInUserGroup=Users in user group
allUsers=All users
couldNotAddUserToUserGroup=Could not add user {0} to user group {1}: {2}
couldNotRemoveUserFromUserGroup=Could not remove user {0} from user group {1}: {2}
enterUserGroupName=Enter user group name
defaultTenant=User group to use for object creation
pagerStateInfo={0,number,#,###}-{1,number,#,###} of {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} of over {2,number,#,###}
yes=Yes
no=No
editUser=Edit User
validated=Validated
groups=Groups
group=Group
errorDeletingUser=При удалении пользователя {0} возникла ошибка: {1}
doYouReallyWantToRemoveUser=Really remove user {0}?
errorTryingToUpdateUser=Error trying to update user {0}: {1}
ownership=Ownership
editObjectOwnership=Edit object ownership
errorObtainingUser=Error obtaining user: {0}
errorObtainingUserGroup=Error obtaining user group: {0}
pleaseWaitUntilUsernameIsResolved=Please wait until user name is resolved
pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is resolved
userNotFound=User {0} not found
usergroupNotFound=User group {0} not found
actionChangeACL=Change ACL
editACLForObject=Edit ACL for ''{0}''
editACL=Редактировать ACL
errorEditingACL=Ошибка при редактировании списка контроля доступа (ACL)
editAnACL=Редактировать список контроля доступа (ACL)
createUserGroup=Создать группу пользователей
removeUserGroup=Удалить группу пользователей
youHaveToSelectAUserGroup=Необходимо выбрать группу пользователей.
doYouReallyWantToRemoveUserGroup=Действительно удалить группу пользователей {0}?
couldNotDeleteUserGroup=Не удалось удалить группу пользователей.
filterUserGroups=Фильтровать группы пользователей...
id=Ид.
displayName=Отображаемое имя
userGroups=Группы пользователей
errorTryingToLoadRoles=Ошибка при попытке загрузки ролей: {0}
filterRoles=Фильтровать роли
actions=Операции
actionEdit=Редактировать
actionRemove=Удалить
actionChangeOwnership=Изменить владение
errorUpdatingOwnership=Ошибка при обновлении владения для объекта {0}
doYouReallyWantToRemoveRole=Действительно удалить роль/роли "{0}"?
errorTryingToDeleteRole=Ошибка при попытке удаления роли "{0}": {1}
pleaseEnterARoleName=Введите имя роли
editRoles=Редактировать роли
otherRoleWithNameAlreadyExists=Уже существует другая роль с именем "{0}".
errorCreatingRole=Ошибка при создании роли "{0}": {1}
errorEditingRoles=Ошибка при редактировании роли "{0}": {1}
usersInUserGroup=Пользователи в группе пользователей
allUsers=Все пользователи
couldNotAddUserToUserGroup=Не удалось добавить пользователя {0} в группу пользователей {1}: {2}
couldNotRemoveUserFromUserGroup=Не удалось удалить пользователя {0} из группы пользователей {1}: {2}
enterUserGroupName=Введите имя группы пользователей
defaultTenant=Группа пользователей для создания объекта
pagerStateInfo={0,number,#,###}-{1,number,#,###} из {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} из более чем {2,number,#,###}
yes=Да
no=Нет
editUser=Редактировать пользователя
validated=Проверено
groups=Группы
group=Группа
errorDeletingUser=Ошибка при удалении пользователя {0}: {1}
doYouReallyWantToRemoveUser=Действительно удалить пользователя {0}?
errorTryingToUpdateUser=Ошибка при попытке обновления пользователя {0}: {1}
ownership=Владение
editObjectOwnership=Редактировать владение объектом
errorObtainingUser=Ошибка при получении пользователя: {0}
errorObtainingUserGroup=Ошибка при получении группы пользователей: {0}
pleaseWaitUntilUsernameIsResolved=Дождитесь разрешения имени пользователя
pleaseWaitUntilUserGroupNameIsResolved=Дождитесь разрешения имени группы пользователей
userNotFound=Пользователь {0} не найден
usergroupNotFound=Группа пользователей {0} не найдена
actionChangeACL=Изменить ACL
editACLForObject=Редактировать ACL для ''{0}''
acl=ACL
errorUpdatingAcl=Error updating ACL: {0}.
allowedActionName=Allowed action name
deniedActionName=Denied action name
errorMessageUserGroupNameNotFound=Did not find user group by name {0}.
successMessageAddedUserGroup=Added user group {0}.
successMessageRemovedUserGroup=Removed user group {0}.
allowedActions=Allowed Actions
deniedActions=Denied Actions
migrateGroupOwner=Migrate group owner for hierarchy
errorDeletingUserGroup=Error deleting user group {0}: {1}
enterAtLeastOneOwner=Please enter at least one owner
removeRole=Remove role
addRole=Add role
couldNotAddRoleToGroup=Role {0} could not be added to group {1}.
roleName=Role Name
enabledForAllUsers=Enabled for all users
couldNotDeleteRole=Could not delete role {0}.
couldNotLoadRoles=Could not load roles.
enterUsername=Enter user name
addUser=Add user
couldNotLoadUsers=Could not load users.
couldNotRemoveRoleFromUser=Could not remove role ''{1}'' from user ''{0}''.
couldNotRemovePermissionFromUser=Could not remove permission ''{1}'' from user ''{0}''.
filterPermission=Filter permission
permission=Permission
errorUpdatingAcl=Ошибка при обновлении ACL: {0}.
allowedActionName=Имя разрешенной операции
deniedActionName=Имя отклоненной операции
errorMessageUserGroupNameNotFound=Не удалось найти группу пользователей пл имени {0}.
successMessageAddedUserGroup=Группа пользователей {0} добавлена.
successMessageRemovedUserGroup=Группа пользователей {0} удалена.
allowedActions=Разрешенные операции
deniedActions=Отклоненные операции
migrateGroupOwner=Выполнить миграцию владельца группы для иерархии
errorDeletingUserGroup=Ошибка при удалении группы пользователей {0}: {1}
enterAtLeastOneOwner=Введите хотя бы одного владельца
removeRole=Удалить роль
addRole=Добавить роль
couldNotAddRoleToGroup=Роль {0} не удалось добавить в группу {1}
roleName=Имя роли
enabledForAllUsers=Активировано для всех пользователей
couldNotDeleteRole=Не удалось удалить роль {0}.
couldNotLoadRoles=Не удалось загрузить роли.
enterUsername=Введите имя пользователя
addUser=Добавить пользователя
couldNotLoadUsers=Не удалось загрузить пользователей.
couldNotRemoveRoleFromUser=Не удалось удалить роль ''{1}'' у пользователя ''{0}''.
couldNotRemovePermissionFromUser=Не удалось удалить полномочия ''{1}'' у пользователя ''{0}''.
filterPermission=Фильтр полномочий
permission=Полномочия
nullUserGroup=<Anonymous UserGroup>
editRolesAndPermissionsForUser=Edit roles and permissions for user {0}
permissionType:Permission Type
editRolesAndPermissionsForUser=Редактировать роли и полномочия для пользователя {0}
permissionType:Тип полномочий
@@ -34,7 +34,7 @@ userDetails=用户详细信息
deleteUser=删除用户
deleteUserQuestion=是否删除用户?
doYouReallyWantToDeleteUser=是否确定删除用户{0}?
doYouReallyWantToDeleteNUsers=Do you really want to delete {0} users?
doYouReallyWantToDeleteNUsers=是否确定删除{0}个用户?
account={0} 账户
save=保存
remove=移除
@@ -108,84 +108,85 @@ settingsRemovedError=无法恢复默认设置
showMoreInfoLogin=请登录,以访问更多功能
dismiss=稍后
moreInfo=更多信息
editACL=Edit ACL
errorEditingACL=Error editing access control list (ACL).
editAnACL=Edit an access control list (ACL)
createUserGroup=Create user group
removeUserGroup=Remove user group
youHaveToSelectAUserGroup=You have to select a user group.
doYouReallyWantToRemoveUserGroup=Do you really want to remove user group {0}?
couldNotDeleteUserGroup=Could not delete user group.
filterUserGroups=Filter user groups...
id=ID
displayName=Display Name
userGroups=User Groups
errorTryingToLoadRoles=Error trying to load roles: {0}
filterRoles=Filter roles
actions=Actions
actionEdit=Edit
actionRemove=Remove
actionChangeOwnership=Change ownership
errorUpdatingOwnership=Error updating ownership of object {0}
doYouReallyWantToRemoveRole=Do you really want to remove role(s) "{0}"?
errorTryingToDeleteRole=Error trying to delete role "{0}": {1}
pleaseEnterARoleName=Please enter a role name
editRoles=Edit Roles
otherRoleWithNameAlreadyExists=Another role with name "{0}" already exists.
errorCreatingRole=Error creating role "{0}": {1}
errorEditingRoles=Error editing role "{0}": {1}
usersInUserGroup=Users in user group
allUsers=All users
couldNotAddUserToUserGroup=Could not add user {0} to user group {1}: {2}
couldNotRemoveUserFromUserGroup=Could not remove user {0} from user group {1}: {2}
enterUserGroupName=Enter user group name
defaultTenant=User group to use for object creation
pagerStateInfo={0,number,#,###}-{1,number,#,###} of {2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###} of over {2,number,#,###}
yes=Yes
no=No
editUser=Edit User
validated=Validated
groups=Groups
group=Group
doYouReallyWantToRemoveUser=Really remove user {0}?
errorTryingToUpdateUser=Error trying to update user {0}: {1}
ownership=Ownership
editObjectOwnership=Edit object ownership
errorObtainingUser=Error obtaining user: {0}
errorObtainingUserGroup=Error obtaining user group: {0}
pleaseWaitUntilUsernameIsResolved=Please wait until user name is resolved
pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is resolved
userNotFound=User {0} not found
usergroupNotFound=User group {0} not found
actionChangeACL=Change ACL
editACLForObject=Edit ACL for ''{0}''
editACL=编辑 ACL
errorEditingACL=编辑访问控制清单 (ACL) 出错。
editAnACL=编辑访问控制清单 (ACL)
createUserGroup=创建用户组
removeUserGroup=移除用户组
youHaveToSelectAUserGroup=需要选择用户组。
doYouReallyWantToRemoveUserGroup=是否确定移除用户组{0}?
couldNotDeleteUserGroup=无法删除用户组。
filterUserGroups=筛选用户组...
id=编号
displayName=显示名称
userGroups=用户组
errorTryingToLoadRoles=尝试加载角色出错:{0}
filterRoles=筛选角色
actions=操作
actionEdit=编辑
actionRemove=移除
actionChangeOwnership=更改所有权
errorUpdatingOwnership=更新对象{0}的所有权出错
doYouReallyWantToRemoveRole=是否确定移除角色 "{0}"?
errorTryingToDeleteRole=尝试删除角色 "{0}" 出错:{1}
pleaseEnterARoleName=请输入角色名称
editRoles=编辑角色
otherRoleWithNameAlreadyExists=名称为 "{0}" 的另一个角色已存在。
errorCreatingRole=创建角色 "{0}" 出错:{1}
errorEditingRoles=编辑角色 "{0}" 出错:{1}
usersInUserGroup=用户组中的用户
allUsers=所有用户
couldNotAddUserToUserGroup=无法将用户{0}添加到用户组{1}:{2}
couldNotRemoveUserFromUserGroup=无法将用户{0}从用户组{1}中移除:{2}
enterUserGroupName=输入用户组名称
defaultTenant=用户对象创建的用户组
pagerStateInfo={0,number,#,###}-{1,number,#,###}/{2,number,#,###}
pagerStateInfo[false]={0,number,#,###}-{1,number,#,###}(超过{2,number,#,###})
yes=是
no=否
editUser=编辑用户
validated=已验证
groups=组
group=组
errorDeletingUser=删除用户{0}时出错:{1}
doYouReallyWantToRemoveUser=是否确定移除用户{0}?
errorTryingToUpdateUser=尝试更新用户{0}时出错:{1}
ownership=所有权
editObjectOwnership=编辑对象所有权
errorObtainingUser=获取用户出错:{0}
errorObtainingUserGroup=获取用户组出错:{0}
pleaseWaitUntilUsernameIsResolved=请等待解析用户名称
pleaseWaitUntilUserGroupNameIsResolved=请等待解析用户组名称
userNotFound=未找到用户{0}
usergroupNotFound=未找到用户组{0}
actionChangeACL=更改 ACL
editACLForObject=为 ''{0}'' 编辑 ACL
acl=ACL
errorUpdatingAcl=Error updating ACL: {0}.
allowedActionName=Allowed action name
deniedActionName=Denied action name
errorMessageUserGroupNameNotFound=Did not find user group by name {0}.
successMessageAddedUserGroup=Added user group {0}.
successMessageRemovedUserGroup=Removed user group {0}.
allowedActions=Allowed Actions
deniedActions=Denied Actions
migrateGroupOwner=Migrate group owner for hierarchy
errorDeletingUserGroup=Error deleting user group {0}: {1}
enterAtLeastOneOwner=Please enter at least one owner
removeRole=Remove role
addRole=Add role
couldNotAddRoleToGroup=Role {0} could not be added to group {1}.
roleName=Role Name
enabledForAllUsers=Enabled for all users
couldNotDeleteRole=Could not delete role {0}.
couldNotLoadRoles=Could not load roles.
enterUsername=Enter user name
addUser=Add user
couldNotLoadUsers=Could not load users.
couldNotRemoveRoleFromUser=Could not remove role ''{1}'' from user ''{0}''.
couldNotRemovePermissionFromUser=Could not remove permission ''{1}'' from user ''{0}''.
filterPermission=Filter permission
permission=Permission
errorUpdatingAcl=更新 ACL 出错:{0}。
allowedActionName=允许的操作名称
deniedActionName=拒绝的操作名称
errorMessageUserGroupNameNotFound=按名称{0}未找到用户组。
successMessageAddedUserGroup=已添加用户组{0}。
successMessageRemovedUserGroup=已移除用户组{0}。
allowedActions=允许的操作
deniedActions=拒绝的操作
migrateGroupOwner=为层次结构迁移组所有者
errorDeletingUserGroup=删除用户组{0}出错:{1}
enterAtLeastOneOwner=请至少输入一个所有者
removeRole=移除角色
addRole=添加角色
couldNotAddRoleToGroup=无法将角色{0}添加到组{1}。
roleName=角色名称
enabledForAllUsers=已为所有用户启用
couldNotDeleteRole=无法删除角色{0}。
couldNotLoadRoles=无法加载角色。
enterUsername=输入用户名称
addUser=添加用户
couldNotLoadUsers=无法加载用户。
couldNotRemoveRoleFromUser=无法将角色 ''{1}'' 从用户 ''{0}'' 中移除。
couldNotRemovePermissionFromUser=无法将权限 ''{1}'' 从用户 ''{0}'' 中移除。
filterPermission=筛选权限
permission=权限
nullUserGroup=<Anonymous UserGroup>
editRolesAndPermissionsForUser=Edit roles and permissions for user {0}
permissionType:Permission Type
editRolesAndPermissionsForUser=为用户{0}编辑角色和权限
permissionType:权限类型
Regular → Executable
+1 -1
View File
@@ -22,7 +22,7 @@
"collectionName":"DataMiningGwtUi",
"folders":[
{
"startingFolderPath":"java/com.sap.sse.datamining.ui/java/com/sap/sse/datamining/ui/client",
"startingFolderPath":"java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client",
"sourceFilters":[
"**/StringMessages*.properties"
],
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

+14 -2
View File
@@ -20,7 +20,7 @@ First of all, make sure you've looked at [http://www.amazon.de/Patterns-Elements
#### Automatic Eclipse plugin installation
The necessary Eclipse plugins described above can be automatically be installed into a newly unzipped version of [Eclipse IDE for Eclipse Committers 4.11.0 "2019-03"](http://www.eclipse.org/downloads/packages/eclipse-ide-eclipse-committers/photonr) by using the script "configuration/installPluginsForEclipse2019-03.sh". In addition, the script applies some updates to plugins packaged with Eclipse itself. To start the plugin installation, run the following command using your Eclipse installation directory as command line parameter for the script:
The necessary Eclipse plugins described above can be automatically be installed into a newly unzipped version of [Eclipse IDE for Eclipse Committers 4.11.0 "2019-03"](https://www.eclipse.org/downloads/packages/release/2019-03/r/eclipse-ide-eclipse-committers) by using the script "configuration/installPluginsForEclipse2019-03.sh". In addition, the script applies some updates to plugins packaged with Eclipse itself. To start the plugin installation, run the following command using your Eclipse installation directory as command line parameter for the script:
./installPluginsForEclipse2019-03.sh "/some/path/on/my/computer/eclipse"
@@ -42,6 +42,18 @@ The script will install the following plugins for your convenience:
* UMLet ([https://www.umlet.com/](https://www.umlet.com/))
* various updates to preinstalled plugins
#### Tuning the Eclipse Installation
Out of the box, two settings in Eclipse avoid a clean workspace. Go to Window - Preferences and change the following two settings:
* Set the "Missing GWT SDK" warning to "Ignore". See screenshot below.
![](ignore-missing-gwt-sdk-warning.png)
* Set the "Plug-in does not export all packages" warning to "Ignore". See screenshot below.
![](ignore-package-not-exported-warning.png)
#### Further optional but recommended installations
1. Cygwin, [http://www.cygwin.com/](http://www.cygwin.com/)
@@ -137,7 +149,7 @@ When a file has "wrong line endings" (line endings are different to what is conf
If you are working with a linux-system and you get the error message `error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory` try to install lib32z1 and lib32stdc++6.
####Steps to consider for using other modules
#### Steps to consider for using other modules
1. For Eclipse Build
* MANIFEST.MF , add module names unter dependencies
* *.gwt.xml , add `<inherits name="-modulename-.-gwt.xml file name-" />`