Merge branch 'master' into ubilabs--tracking_app--develop

This commit is contained in:
Bennet Brunsen committed 2015-06-25 09:48:13 +02:00
commit 742c71c637
41 files changed
+644 -341

No files matched your search

+25 -24
View File
@@ -660,30 +660,31 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
if [[ ${PIPESTATUS[0]} != 0 ]]; then
exit 103
fi
adb emu kill
echo "Downloading image (sys-img-${ANDROID_ABI}-android-${TEST_API})..." | tee -a $START_DIR/build.log
echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter sys-img-${ANDROID_ABI}-android-${TEST_API} --no-ui --force --all > /dev/null
echo no | "$ANDROID" create avd --name ${AVD_NAME} --target android-${TEST_API} --abi ${ANDROID_ABI} --force -p ${START_DIR}/emulator
echo "Starting emulator..." | tee -a $START_DIR/build.log
emulator -avd ${AVD_NAME} -no-skin -no-audio -no-window &
echo "Waiting for startup..." | tee -a $START_DIR/build.log
adb wait-for-device
sleep 60
$PROJECT_HOME/configuration/androidWaitForEmulator.sh
if [[ $? != 0 ]]; then
adb emu kill
"$ANDROID" delete avd --name ${AVD_NAME}
exit 102
fi
adb shell input keyevent 82 &
./gradlew deviceCheck connectedCheck | tee -a $START_DIR/build.log
if [[ ${PIPESTATUS[0]} != 0 ]]; then
adb emu kill
"$ANDROID" delete avd --name ${AVD_NAME}
exit 101
fi
adb emu kill
"$ANDROID" delete avd --name ${AVD_NAME}
# TODO find a way that the emulator test is stable in hudson
# adb emu kill
# echo "Downloading image (sys-img-${ANDROID_ABI}-android-${TEST_API})..." | tee -a $START_DIR/build.log
# echo yes | "$ANDROID" update sdk $ANDROID_OPTIONS --filter sys-img-${ANDROID_ABI}-android-${TEST_API} --no-ui --force --all > /dev/null
# echo no | "$ANDROID" create avd --name ${AVD_NAME} --target android-${TEST_API} --abi ${ANDROID_ABI} --force -p ${START_DIR}/emulator
# echo "Starting emulator..." | tee -a $START_DIR/build.log
# emulator -avd ${AVD_NAME} -no-skin -no-audio -no-window &
# echo "Waiting for startup..." | tee -a $START_DIR/build.log
# adb wait-for-device
# sleep 60
# $PROJECT_HOME/configuration/androidWaitForEmulator.sh
# if [[ $? != 0 ]]; then
# adb emu kill
# "$ANDROID" delete avd --name ${AVD_NAME}
# exit 102
# fi
# adb shell input keyevent 82 &
# ./gradlew deviceCheck connectedCheck | tee -a $START_DIR/build.log
# if [[ ${PIPESTATUS[0]} != 0 ]]; then
# adb emu kill
# "$ANDROID" delete avd --name ${AVD_NAME}
# exit 101
# fi
# adb emu kill
# "$ANDROID" delete avd --name ${AVD_NAME}
fi
else
echo "INFO: Deactivating mobile modules"
@@ -8,7 +8,6 @@ import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.AbstractTimePoint;
/**
* A compact representation of a GPS fix which collects all primitive-typed attributes in one object to avoid
@@ -42,7 +41,7 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
private final double latDeg;
private final double lngDeg;
private final long timePointAsMillis;
private final TimePoint timePoint;
/**
* Tells if in the containing {@link DynamicGPSFixTrackImpl} this fix is considered valid. This cache
@@ -78,15 +77,6 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
}
}
private class CompactTimePoint extends AbstractTimePoint implements TimePoint {
private static final long serialVersionUID = -2470922642359937437L;
@Override
public long asMillis() {
return timePointAsMillis;
}
}
private class CompactEstimatedSpeedBearing extends AbstractBearing {
private static final long serialVersionUID = 8549231429037883121L;
@@ -113,7 +103,7 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
public CompactGPSFixImpl(Position position, TimePoint timePoint) {
latDeg = position.getLatDeg();
lngDeg = position.getLngDeg();
timePointAsMillis = timePoint==null?-1:timePoint.asMillis();
this.timePoint = timePoint;
}
public CompactGPSFixImpl(GPSFix gpsFix) {
@@ -132,7 +122,7 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
@Override
public TimePoint getTimePoint() {
return new CompactTimePoint();
return timePoint;
}
@Override
@@ -0,0 +1,38 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sse.common.TimePoint;
public class IsIndividualRecallDisplayedAnalyzer extends RaceLogAnalyzer<Boolean> {
private final IndividualRecallFinder displayedFinder;
private final IndividualRecallFinder removedFinder;
public IsIndividualRecallDisplayedAnalyzer(RaceLog raceLog) {
this(raceLog, null);
}
public IsIndividualRecallDisplayedAnalyzer(RaceLog raceLog, TimePoint at) {
this(raceLog, new IndividualRecallDisplayedFinder(raceLog, at), new IndividualRecallRemovedFinder(raceLog, at), at);
}
public IsIndividualRecallDisplayedAnalyzer(RaceLog raceLog, IndividualRecallDisplayedFinder displayedFinder,
IndividualRecallRemovedFinder removedFinder, TimePoint at) {
super(raceLog);
this.displayedFinder = displayedFinder;
this.removedFinder = removedFinder;
}
@Override
protected Boolean performAnalysis() {
TimePoint displayedAt = displayedFinder.analyze();
TimePoint removedAt = removedFinder.analyze();
if (displayedAt != null) {
if (removedAt == null || displayedAt.after(removedAt)) {
return true;
}
}
return false;
}
}
@@ -30,4 +30,9 @@ public class RaceLogProtestStartTimeEventImpl extends RaceLogEventImpl implement
return protestStartTime;
}
@Override
public String getShortInfo() {
return "protestStartTime=" + protestStartTime;
}
}
@@ -30,7 +30,7 @@ public class SimpleRaceLogIdentifierImpl implements SimpleRaceLogIdentifier {
@Override
public String toString() {
return "SimpleRaceLogIdentifier [regattaLikeParentName=" + regattaLikeParentName + ", raceCloumnName=" + raceColumnName
return "SimpleRaceLogIdentifier [regattaLikeParentName=" + regattaLikeParentName + ", raceColumnName=" + raceColumnName
+ ", fleetName=" + fleetName + "]";
}
@@ -15,6 +15,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.IndividualRecallDi
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.IndividualRecallRemovedFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.IsFinishedAnalyzer;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.IsInFinishingPhaseAnalyzer;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.IsIndividualRecallDisplayedAnalyzer;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogChangedVisitor;
@@ -28,9 +29,7 @@ import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProce
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureChangedListener;
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
/**
* Base class for all your {@link RacingProcedure}s.
@@ -42,10 +41,7 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener implements RacingProcedure,
RaceLogChangedListener {
/**
* The time since race start after which the X-ray flag has to go down
*/
private final static Duration individualRecallRemovalTimeout = Duration.ONE_MINUTE.times(4);
private final static long individualRecallRemovalTimeout = 4 * 60 * 1000; // minutes * seconds * milliseconds
private RaceStateEventScheduler scheduler;
@@ -55,35 +51,41 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
private final RacingProcedureConfiguration configuration;
private final RacingProcedureChangedListeners<? extends RacingProcedureChangedListener> changedListeners;
private final IsIndividualRecallDisplayedAnalyzer isRecallDisplayedAnalyzer;
private final IndividualRecallDisplayedFinder recallDisplayedFinder;
private final IndividualRecallRemovedFinder recallRemovedFinder;
private final FinishingTimeFinder finishingTimeFinder;
private final FinishedTimeFinder finishedTimeFinder;
private final RaceLogEventVisitor raceLogListener;
private final StartTimeFinder startTimeFinder;
private boolean cachedIsIndividualRecallDisplayed;
/**
* When calling me, call {@link BaseRacingProcedure#update()} afterwards!
* @param raceLogResolver TODO
*
* @param raceLogResolver
* is required for a {@link StartTimeFinder} in order to make individual recall timeouts depend on start
* time rather than the time the individual recall was issued
*/
public BaseRacingProcedure(RaceLog raceLog, AbstractLogEventAuthor author, RaceLogEventFactory factory,
RacingProcedureConfiguration configuration, RaceLogResolver raceLogResolver) {
if (configuration == null) {
throw new IllegalArgumentException("configuration must not be null");
}
this.raceLog = raceLog;
this.author = author;
this.factory = factory;
this.configuration = configuration;
this.changedListeners = createChangedListenerContainer();
this.isRecallDisplayedAnalyzer = new IsIndividualRecallDisplayedAnalyzer(raceLog);
this.recallDisplayedFinder = new IndividualRecallDisplayedFinder(raceLog);
this.recallRemovedFinder = new IndividualRecallRemovedFinder(raceLog);
this.finishingTimeFinder = new FinishingTimeFinder(raceLog);
this.finishedTimeFinder = new FinishedTimeFinder(raceLog);
this.startTimeFinder = new StartTimeFinder(raceLogResolver, raceLog);
// Use the following in order to initialize a start time finder once it's needed for start time-dependent individual recall timeouts
// this.startTimeFinder = new StartTimeFinder(raceLogResolver, raceLog);
this.raceLogListener = new RaceLogChangedVisitor(this);
this.raceLog.addListener(raceLogListener);
@@ -131,7 +133,7 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
break;
case RUNNING:
if (isIndividualRecallDisplayed()) {
rescheduleIndividualRecallTimeout();
rescheduleIndividualRecallTimeout(recallDisplayedFinder.analyze());
}
break;
default:
@@ -139,10 +141,6 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
}
}
private TimePoint getStartTime() {
return startTimeFinder.analyze().getStartTime();
}
@Override
public boolean isIndividualRecallDisplayed() {
return cachedIsIndividualRecallDisplayed;
@@ -150,10 +148,10 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
@Override
public boolean isIndividualRecallDisplayed(TimePoint at) {
final TimePoint individualRecallDisplayedTime = getIndividualRecallDisplayedTime();
final TimePoint individualRecallRemovalTime = getIndividualRecallRemovalTime();
return (hasIndividualRecall() && individualRecallDisplayedTime != null && !individualRecallDisplayedTime.after(at) &&
individualRecallRemovalTime != null && !individualRecallRemovalTime.after(at));
if (hasIndividualRecall()) {
return new IsIndividualRecallDisplayedAnalyzer(getRaceLog(), at).analyze();
}
return false;
}
@Override
@@ -166,20 +164,17 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
@Override
public TimePoint getIndividualRecallRemovalTime() {
final TimePoint result;
final TimePoint raceStartTime = getStartTime();
final TimePoint removedEvent;
if (hasIndividualRecall() && (removedEvent = recallRemovedFinder.analyze()) != null && (raceStartTime == null || removedEvent.after(raceStartTime))) {
result = removedEvent;
} else {
final TimePoint individualRecallDisplayedTime = getIndividualRecallDisplayedTime();
if (individualRecallDisplayedTime != null && raceStartTime != null) {
result = raceStartTime.plus(individualRecallRemovalTimeout);
} else {
result = null;
TimePoint displayed = getIndividualRecallDisplayedTime();
if (hasIndividualRecall()) {
TimePoint removedEvent = recallRemovedFinder.analyze();
if (removedEvent != null && (displayed == null || removedEvent.after(displayed))) {
return removedEvent;
}
}
return result;
if (displayed != null) {
return displayed.plus(individualRecallRemovalTimeout);
}
return null;
}
@Override
@@ -217,21 +212,18 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
}
protected void update() {
// TODO an X-ray up event with a time point in the future will not be recognized here because at the current time the flag is not displayed and no other race log event will trigger the update; we'd need to schedule another state event; as long as clocks are set correctly, additional transmission time will make this unlikely
boolean isRecallDisplayed = isIndividualRecallDisplayed(MillisecondsTimePoint.now());
boolean isRecallDisplayed = isRecallDisplayedAnalyzer.analyze();
if (cachedIsIndividualRecallDisplayed != isRecallDisplayed) {
cachedIsIndividualRecallDisplayed = isRecallDisplayed;
if (!cachedIsIndividualRecallDisplayed) {
// individual recall was removed; no need to schedule an event for removal
if (cachedIsIndividualRecallDisplayed) {
changedListeners.onIndividualRecallDisplayed(this);
rescheduleIndividualRecallTimeout(recallDisplayedFinder.analyze());
} else {
changedListeners.onIndividualRecallRemoved(this);
unscheduleStateEvent(RaceStateEvents.INDIVIDUAL_RECALL_TIMEOUT);
}
}
// (re-)schedule the individual recall removal in any case; the removal time may have changed
if (cachedIsIndividualRecallDisplayed) {
changedListeners.onIndividualRecallDisplayed(this);
rescheduleIndividualRecallTimeout();
}
}
// always call listeners for changed flag, as this does not only affect recall, but also
// changes start procedure, for which some text elements need to be updated
@@ -239,9 +231,9 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
changedListeners.onActiveFlagsChanged(this);
}
private void rescheduleIndividualRecallTimeout() {
private void rescheduleIndividualRecallTimeout(TimePoint displayTime) {
unscheduleStateEvent(RaceStateEvents.INDIVIDUAL_RECALL_TIMEOUT);
scheduleStateEvents(new RaceStateEventImpl(getIndividualRecallRemovalTime(), RaceStateEvents.INDIVIDUAL_RECALL_TIMEOUT));
scheduleStateEvents(new RaceStateEventImpl(displayTime.plus(individualRecallRemovalTimeout), RaceStateEvents.INDIVIDUAL_RECALL_TIMEOUT));
}
protected void scheduleStateEvents(RaceStateEvent stateEvent) {
@@ -61,7 +61,7 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
private DynamicTrackedRace trackedRace;
private Competitor c1, c2;
private void setUp(Function<Competitor, Double> timeOnTimeFactors, Function<Competitor, Double> timeOnDistanceFactors) {
private void setUp(TimeOnTimeFactorMapping timeOnTimeFactors, Function<Competitor, Double> timeOnDistanceFactors) {
c1 = TrackBasedTest.createCompetitor("FastBoat");
c2 = TrackBasedTest.createCompetitor("SlowBoat");
trackedRace = createTrackedRace(Arrays.asList(c1, c2), timeOnTimeFactors, timeOnDistanceFactors);
@@ -70,7 +70,7 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
assertSame(RankingMetrics.TIME_ON_TIME_AND_DISTANCE, trackedRace.getTrackedRegatta().getRegatta().getRankingMetricType());
}
private DynamicTrackedRace createTrackedRace(Iterable<Competitor> competitors, Function<Competitor, Double> timeOnTimeFactors, Function<Competitor, Double> timeOnDistanceFactors) {
private DynamicTrackedRace createTrackedRace(Iterable<Competitor> competitors, TimeOnTimeFactorMapping timeOnTimeFactors, Function<Competitor, Double> timeOnDistanceFactors) {
final TimePoint timePointForFixes = MillisecondsTimePoint.now();
BoatClassImpl boatClass = new BoatClassImpl("Some Handicap Boat Class", /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
@@ -0,0 +1,47 @@
package com.sap.sailing.domain.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Collections;
import java.util.UUID;
import org.junit.Test;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
import com.sap.sailing.domain.ranking.RankingMetric;
import com.sap.sailing.domain.ranking.TimeOnTimeAndDistanceRankingMetric;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
public class SerializeRankingMetricTest extends AbstractSerializationTest {
@Test
public void testTimeOnTimeAndDistanceRankingMetricSerialization() throws ClassNotFoundException, IOException {
final BoatClass _49er = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
final TrackedRace trackedRace = new DynamicTrackedRaceImpl(new DynamicTrackedRegattaImpl(
new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, "Regatta", /* boatClass */ _49er,
/* startDate */ null, /* endDate */ null, /* trackedRegattaRegistry */ null,
new LowPoint(), UUID.randomUUID(), /* courseArea */ null)),
new RaceDefinitionImpl("Race", new CourseImpl("Course", Collections.<Waypoint>emptyList()) ,
/* boatClass */ _49er, Collections.<Competitor>emptySet()),
Collections.<Sideline>emptyList(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, 0l, 0l, 0l,
false, TimeOnTimeAndDistanceRankingMetric::new, null);
RankingMetric clone = cloneBySerialization(trackedRace.getRankingMetric(), DomainFactory.INSTANCE);
assertNotNull(clone);
assertTrue(clone instanceof TimeOnTimeAndDistanceRankingMetric);
}
}
@@ -41,6 +41,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.Util;
import com.sap.sse.common.WithID;
import com.sap.sse.common.impl.TimeRangeImpl;
@@ -255,7 +256,15 @@ public class TopLevelMasterData implements Serializable {
}
public void setMasterDataExportFlagOnRaceColumns(boolean flagValue) {
for (LeaderboardGroup group : leaderboardGroups) {
// collect all leaderboard groups for all events that will be touched during serialization
final Set<LeaderboardGroup> allLeaderboardGroups = new HashSet<>();
allLeaderboardGroups.addAll(leaderboardGroups);
for (Entry<LeaderboardGroup, Set<Event>> i : eventForLeaderboardGroup.entrySet()) {
for (Event e : i.getValue()) {
Util.addAll(e.getLeaderboardGroups(), allLeaderboardGroups);
}
}
for (LeaderboardGroup group : allLeaderboardGroups) {
for (Leaderboard leaderboard : group.getLeaderboards()) {
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
raceColumn.setMasterDataExportOngoingThreadFlag(true);
@@ -227,6 +227,20 @@ public interface PolarDataService {
LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException;
void insertExistingFixes(TrackedRace trackedRace);
/**
*
* @param boatClass When polars of this boat class change, the listener will be notified. May not be null.
* @param listener may not be null
*/
void registerListener(BoatClass boatClass, PolarsChangedListener listener);
/**
*
* @param boatClass
* @param listener
*/
void unregisterListener(BoatClass boatClass, PolarsChangedListener listener);
}
@@ -0,0 +1,10 @@
package com.sap.sailing.domain.polars;
public interface PolarsChangedListener {
/**
* Is called when the polars of the boat class you registered the listener for changed
*/
void polarsChanged();
}
@@ -10,6 +10,7 @@ import java.util.function.Supplier;
import java.util.stream.StreamSupport;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CompetitorImpl;
@@ -24,6 +25,7 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
import com.sap.sailing.domain.tracking.WindPositionMode;
import com.sap.sailing.domain.tracking.impl.AbstractRaceRankComparator;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
@@ -281,17 +283,20 @@ public abstract class AbstractRankingMetric implements RankingMetric {
/**
* Constructs a comparator based on the results of
* {@link #getWindwardDistanceTraveled(Competitor, TimePoint, WindLegTypeAndLegBearingCache)} where competitors are
* "less" than other competitors ("better") if they have a greater windward distance traveled.
* "less" than other competitors ("better") if they are in a later leg or, if in the same leg, have a greater
* windward distance traveled. If both competitors have already finished the race, the finishing time is compared.
*/
private Comparator<Competitor> getWindwardDistanceTraveledComparator(final TimePoint timePoint, final WindLegTypeAndLegBearingCache cache) {
final Map<Competitor, Distance> windwardDistanceTraveledPerCompetitor = new HashMap<>();
for (final Competitor competitor : getCompetitors()) {
windwardDistanceTraveledPerCompetitor.put(competitor, getWindwardDistanceTraveled(competitor, timePoint, cache));
}
final Comparator<Distance> nullsFirstDistanceComparator = Comparator.nullsFirst(Comparator.naturalOrder());
return (c1, c2) -> nullsFirstDistanceComparator.compare(
windwardDistanceTraveledPerCompetitor.get(c2),
windwardDistanceTraveledPerCompetitor.get(c1));
return new AbstractRaceRankComparator<Distance>(trackedRace, timePoint, /* lessIsBetter */ false) {
@Override
protected Distance getComparisonValueForSameLeg(Competitor competitor) {
return windwardDistanceTraveledPerCompetitor.get(competitor);
}
};
}
/**
@@ -508,8 +513,8 @@ public abstract class AbstractRankingMetric implements RankingMetric {
if (legTo.hasFinishedLeg(timePoint)) {
// calculate actual time it takes who to reach the end of the leg starting at timePoint:
final TimePoint whosLegFinishTime = legWho.getFinishTime();
if (whosLegFinishTime != null) {
// who's leg finishing time is known; we don't need to extrapolate
if (whosLegFinishTime != null && !whosLegFinishTime.after(timePoint)) {
// who's leg finishing time is known and is already reached at timePoint; we don't need to extrapolate
toEndOfLegOrTo = timePoint.until(whosLegFinishTime);
} else {
assert getWindwardDistanceTraveled(legTo.getCompetitor(), legTo.hasFinishedLeg(timePoint)?legTo.getFinishTime():timePoint, cache).compareTo(
@@ -601,33 +606,39 @@ public abstract class AbstractRankingMetric implements RankingMetric {
} else {
Distance d = Distance.NULL;
boolean count = false; // start counting only once the "from" waypoint has been found
for (final TrackedLeg trackedLeg : getTrackedRace().getTrackedLegs()) {
count = count || trackedLeg.getLeg().getFrom() == from;
if (count) {
final TrackedLegOfCompetitor trackedLegOfCompetitor = trackedLeg.getTrackedLeg(competitor);
if (trackedLegOfCompetitor.hasStartedLeg(timePoint)) {
if (!trackedLegOfCompetitor.hasFinishedLeg(timePoint)) {
// partial distance sailed:
final Position estimatedPosition = getTrackedRace().getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolate */ true);
if (estimatedPosition != null) {
final Distance windwardDistanceFromLegStart = trackedLeg.getWindwardDistanceFromLegStart(estimatedPosition, cache);
final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
if (legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) {
d = d.add(legWindwardDistance);
} else {
// if the competitor is currently at the mark rounding, the windward distance within the leg may
// be negative; don't reduce the distance in this case
if (windwardDistanceFromLegStart.getMeters() > 0) {
d = d.add(windwardDistanceFromLegStart);
final Course course = getTrackedRace().getRace().getCourse();
course.lockForRead();
try {
for (final TrackedLeg trackedLeg : getTrackedRace().getTrackedLegs()) {
count = count || trackedLeg.getLeg().getFrom() == from;
if (count) {
final TrackedLegOfCompetitor trackedLegOfCompetitor = trackedLeg.getTrackedLeg(competitor);
if (trackedLegOfCompetitor.hasStartedLeg(timePoint)) {
if (!trackedLegOfCompetitor.hasFinishedLeg(timePoint)) {
// partial distance sailed:
final Position estimatedPosition = getTrackedRace().getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolate */ true);
if (estimatedPosition != null) {
final Distance windwardDistanceFromLegStart = trackedLeg.getWindwardDistanceFromLegStart(estimatedPosition, cache);
final Distance legWindwardDistance = trackedLeg.getWindwardDistance(cache);
if (legWindwardDistance.compareTo(windwardDistanceFromLegStart) < 0) {
d = d.add(legWindwardDistance);
} else {
// if the competitor is currently at the mark rounding, the windward distance within the leg may
// be negative; don't reduce the distance in this case
if (windwardDistanceFromLegStart.getMeters() > 0) {
d = d.add(windwardDistanceFromLegStart);
}
}
}
break;
} else {
d = d.add(trackedLeg.getWindwardDistance(cache));
}
break;
} else {
d = d.add(trackedLeg.getWindwardDistance(cache));
}
}
}
} finally {
course.unlockAfterRead();
}
result = d;
}
@@ -0,0 +1,9 @@
package com.sap.sailing.domain.ranking;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sse.common.Duration;
import com.sap.sse.util.SerializableFunction;
@FunctionalInterface
public interface TimeOnDistanceAllowancePerNauticalMileMap extends SerializableFunction<Competitor, Duration> {
}
@@ -3,7 +3,6 @@ package com.sap.sailing.domain.ranking;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import com.sap.sailing.domain.base.Competitor;
@@ -52,9 +51,9 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
public final static RankingMetricConstructor CONSTRUCTOR = TimeOnTimeAndDistanceRankingMetric::new;
private final Function<Competitor, Double> timeOnTimeFactor;
private final TimeOnTimeFactorMapping timeOnTimeFactor;
private final Function<Competitor, Duration> timeOnDistanceFactorNauticalMile;
private final TimeOnDistanceAllowancePerNauticalMileMap timeOnDistanceFactorNauticalMile;
/**
* The regular constructor that can also be used as <code>TimeOnTimeAndDistanceRankingMetric::new</code>
@@ -72,8 +71,8 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
* its regatta, handicap mappings can be passed directly and overrule anything defined for the competitor or
* on the regatta.
*/
public TimeOnTimeAndDistanceRankingMetric(final TrackedRace trackedRace, Function<Competitor, Double> timeOnTimeFactor,
Function<Competitor, Duration> timeOnDistanceFactorInSecondsPerNauticalMile) {
public TimeOnTimeAndDistanceRankingMetric(final TrackedRace trackedRace, TimeOnTimeFactorMapping timeOnTimeFactor,
TimeOnDistanceAllowancePerNauticalMileMap timeOnDistanceFactorInSecondsPerNauticalMile) {
super(trackedRace);
this.timeOnTimeFactor = timeOnTimeFactor;
this.timeOnDistanceFactorNauticalMile = timeOnDistanceFactorInSecondsPerNauticalMile;
@@ -0,0 +1,8 @@
package com.sap.sailing.domain.ranking;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sse.util.SerializableFunction;
@FunctionalInterface
public interface TimeOnTimeFactorMapping extends SerializableFunction<Competitor, Double> {
}
@@ -0,0 +1,129 @@
package com.sap.sailing.domain.tracking.impl;
import java.util.Collections;
import java.util.Comparator;
import java.util.NavigableSet;
import java.util.SortedSet;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.TimePoint;
/**
* Compares two competitors by their ranking in the overall race for a given time point. Competitors who haven't started
* the first leg are all equally ranked last. Competitors in different legs are ranked by inverse leg index: the higher
* the number of the leg the lesser (better) the rank. Competitors in the same leg are ranked by their windward distance
* to go in that leg, requiring wind data or estimates to be available for the given time point. The wind is estimated at
* the middle of the leg for consistent ordering, so the same wind data will be used for comparing all competitors in the
* same leg at a given point in time.
* <p>
*
* This comparator assumes that the race's {@link Course} remains unchanged from the time this comparator's constructor
* is invoked and the last call to {@link #compare(Competitor, Competitor)} on this comparator. This should be obvious
* because course changes have an effect on the race's leg structure and therefore on the foundations for ranking.
* Clients should use {@link Course#lockForRead()} and {@link Course#unlockAfterRead()} to frame the construction and
* use of this comparator.<p>
*
* Two different competitors may end up being ranked equal by this comparator. So take care and don't use this
* comparator class when inserting into an {@link SortedSet} when you want something like a ranking. It may overwrite
* existing entries. Use {@link Collections#sort(java.util.List, Comparator)} instead.
*
* @author Axel Uhl (d043530)
*
*/
public abstract class AbstractRaceRankComparator<C extends Comparable<C>> implements Comparator<Competitor> {
private final TrackedRace trackedRace;
private final TimePoint timePoint;
private final DummyMarkPassingWithTimePointOnly markPassingWithTimePoint;
private final boolean lessIsBetter;
/**
* @param lessIsBetter
* tells whether lesser return values for {@link #getComparisonValueForSameLeg(Competitor)} denote a
* better competitor ranking or not.
*/
public AbstractRaceRankComparator(TrackedRace trackedRace, TimePoint timePoint, boolean lessIsBetter) {
super();
this.trackedRace = trackedRace;
this.timePoint = timePoint;
this.markPassingWithTimePoint = new DummyMarkPassingWithTimePointOnly(timePoint);
this.lessIsBetter = lessIsBetter;
}
@Override
public int compare(Competitor o1, Competitor o2) {
int result;
if (o1 == o2) {
result = 0;
} else {
NavigableSet<MarkPassing> o1MarkPassings = trackedRace.getMarkPassings(o1);
NavigableSet<MarkPassing> o1MarkPassingsBeforeTimePoint;
MarkPassing o1LastMarkPassingBeforeTimePoint = null;
int o1MarkPassingsBeforeTimePointSize;
TrackedLegOfCompetitor o1Leg;
trackedRace.lockForRead(o1MarkPassings);
try {
o1MarkPassingsBeforeTimePoint = o1MarkPassings.headSet(
markPassingWithTimePoint, /* inclusive */true);
o1MarkPassingsBeforeTimePointSize = o1MarkPassingsBeforeTimePoint.size();
if (o1MarkPassingsBeforeTimePointSize > 0) {
o1LastMarkPassingBeforeTimePoint = o1MarkPassingsBeforeTimePoint.last();
}
o1Leg = trackedRace.getCurrentLeg(o1, timePoint);
} finally {
trackedRace.unlockAfterRead(o1MarkPassings);
}
NavigableSet<MarkPassing> o2MarkPassings = trackedRace.getMarkPassings(o2);
NavigableSet<MarkPassing> o2MarkPassingsBeforeTimePoint;
MarkPassing o2LastMarkPassingBeforeTimePoint = null;
int o2MarkPassingsBeforeTimePointSize;
TrackedLegOfCompetitor o2Leg;
trackedRace.lockForRead(o2MarkPassings);
try {
o2MarkPassingsBeforeTimePoint = o2MarkPassings.headSet(markPassingWithTimePoint, /* inclusive */true);
o2MarkPassingsBeforeTimePointSize = o2MarkPassingsBeforeTimePoint.size();
if (o2MarkPassingsBeforeTimePointSize > 0) {
o2LastMarkPassingBeforeTimePoint = o2MarkPassingsBeforeTimePoint.last();
}
o2Leg = trackedRace.getCurrentLeg(o2, timePoint);
} finally {
trackedRace.unlockAfterRead(o2MarkPassings);
}
result = o2MarkPassingsBeforeTimePointSize - o1MarkPassingsBeforeTimePointSize; // inverted: more legs means
// smaller rank
if (result == 0 && o1MarkPassingsBeforeTimePointSize > 0) {
// Competitors are on same leg and both have already started the first leg.
// TrackedLegOfCompetitor comparison also correctly uses finish times for a leg
// in case we have the final leg, so both competitors finished the race.
if (o1Leg == null) {
// both must already have finished race; sort by race finish time: earlier time means smaller
// (better) rank
result = o1LastMarkPassingBeforeTimePoint.getTimePoint().compareTo(
o2LastMarkPassingBeforeTimePoint.getTimePoint());
} else {
if (o2Leg == null) {
result = 1; // o1Leg != null, so o1 has started leg already, o2 hasn't
} else {
if (o1Leg.getLeg() != o2Leg.getLeg()) {
// strange: both have the same number of mark passings but are in different legs; something is
// broken, but we can only try our best:
result = trackedRace.getRace().getCourse().getLegs().indexOf(o1Leg.getLeg()) -
trackedRace.getRace().getCourse().getLegs().indexOf(o2Leg.getLeg());
} else {
// competitors are in same leg; compare their windward distance to go
final C wwdtgO1 = getComparisonValueForSameLeg(o1);
final C wwdtgO2 = getComparisonValueForSameLeg(o2);
result = wwdtgO1==null?wwdtgO2==null?0:-1:wwdtgO2==null?1:(lessIsBetter?1:-1)*wwdtgO1.compareTo(wwdtgO2);
}
}
}
}
}
return result;
}
protected abstract C getComparisonValueForSameLeg(Competitor competitor);
}
@@ -4,13 +4,11 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.NavigableSet;
import java.util.SortedSet;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
@@ -39,17 +37,11 @@ import com.sap.sse.common.TimePoint;
* @author Axel Uhl (d043530)
*
*/
public class RaceRankComparator implements Comparator<Competitor> {
private final TrackedRace trackedRace;
private final TimePoint timePoint;
private final DummyMarkPassingWithTimePointOnly markPassingWithTimePoint;
public class RaceRankComparator extends AbstractRaceRankComparator<Distance> {
private final Map<Competitor, Distance> windwardDistanceToGoInLegCache;
public RaceRankComparator(TrackedRace trackedRace, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
super();
this.trackedRace = trackedRace;
this.timePoint = timePoint;
this.markPassingWithTimePoint = new DummyMarkPassingWithTimePointOnly(timePoint);
super(trackedRace, timePoint, /* lessIsBetter */ true);
this.windwardDistanceToGoInLegCache = new HashMap<Competitor, Distance>();
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
final TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, timePoint);
@@ -61,74 +53,7 @@ public class RaceRankComparator implements Comparator<Competitor> {
}
@Override
public int compare(Competitor o1, Competitor o2) {
int result;
if (o1 == o2) {
result = 0;
} else {
NavigableSet<MarkPassing> o1MarkPassings = trackedRace.getMarkPassings(o1);
NavigableSet<MarkPassing> o1MarkPassingsBeforeTimePoint;
MarkPassing o1LastMarkPassingBeforeTimePoint = null;
int o1MarkPassingsBeforeTimePointSize;
TrackedLegOfCompetitor o1Leg;
trackedRace.lockForRead(o1MarkPassings);
try {
o1MarkPassingsBeforeTimePoint = o1MarkPassings.headSet(
markPassingWithTimePoint, /* inclusive */true);
o1MarkPassingsBeforeTimePointSize = o1MarkPassingsBeforeTimePoint.size();
if (o1MarkPassingsBeforeTimePointSize > 0) {
o1LastMarkPassingBeforeTimePoint = o1MarkPassingsBeforeTimePoint.last();
}
o1Leg = trackedRace.getCurrentLeg(o1, timePoint);
} finally {
trackedRace.unlockAfterRead(o1MarkPassings);
}
NavigableSet<MarkPassing> o2MarkPassings = trackedRace.getMarkPassings(o2);
NavigableSet<MarkPassing> o2MarkPassingsBeforeTimePoint;
MarkPassing o2LastMarkPassingBeforeTimePoint = null;
int o2MarkPassingsBeforeTimePointSize;
TrackedLegOfCompetitor o2Leg;
trackedRace.lockForRead(o2MarkPassings);
try {
o2MarkPassingsBeforeTimePoint = o2MarkPassings.headSet(markPassingWithTimePoint, /* inclusive */true);
o2MarkPassingsBeforeTimePointSize = o2MarkPassingsBeforeTimePoint.size();
if (o2MarkPassingsBeforeTimePointSize > 0) {
o2LastMarkPassingBeforeTimePoint = o2MarkPassingsBeforeTimePoint.last();
}
o2Leg = trackedRace.getCurrentLeg(o2, timePoint);
} finally {
trackedRace.unlockAfterRead(o2MarkPassings);
}
result = o2MarkPassingsBeforeTimePointSize - o1MarkPassingsBeforeTimePointSize; // inverted: more legs means
// smaller rank
if (result == 0 && o1MarkPassingsBeforeTimePointSize > 0) {
// Competitors are on same leg and both have already started the first leg.
// TrackedLegOfCompetitor comparison also correctly uses finish times for a leg
// in case we have the final leg, so both competitors finished the race.
if (o1Leg == null) {
// both must already have finished race; sort by race finish time: earlier time means smaller
// (better) rank
result = o1LastMarkPassingBeforeTimePoint.getTimePoint().compareTo(
o2LastMarkPassingBeforeTimePoint.getTimePoint());
} else {
if (o2Leg == null) {
result = 1; // o1Leg != null, so o1 has started leg already, o2 hasn't
} else {
if (o1Leg.getLeg() != o2Leg.getLeg()) {
// strange: both have the same number of mark passings but are in different legs; something is
// broken, but we can only try our best:
result = trackedRace.getRace().getCourse().getLegs().indexOf(o1Leg.getLeg()) -
trackedRace.getRace().getCourse().getLegs().indexOf(o2Leg.getLeg());
} else {
// competitors are in same leg; compare their windward distance to go
final Distance wwdtgO1 = windwardDistanceToGoInLegCache.get(o1);
final Distance wwdtgO2 = windwardDistanceToGoInLegCache.get(o2);
result = wwdtgO1==null?wwdtgO2==null?0:-1:wwdtgO2==null?1:wwdtgO1.compareTo(wwdtgO2);
}
}
}
}
}
return result;
protected Distance getComparisonValueForSameLeg(Competitor o1) {
return windwardDistanceToGoInLegCache.get(o1);
}
}
File mode changed.
View File
File mode changed.
@@ -189,7 +189,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
StructureImportManagementPanel structureImportUrlsManagementPanel = new StructureImportManagementPanel(sailingService, this, getStringMessages(), this, eventManagementPanel);
panel.addToTabPanel(connectorsTabPanel, new DefaultRefreshableAdminConsolePanel<StructureImportManagementPanel>(structureImportUrlsManagementPanel),
getStringMessages().structureImportUrls(), Permission.MANAGE_STRUCTURE_IMPORT_URLS);
getStringMessages().manage2Sail() + " " + getStringMessages().regattaStructureImport(), Permission.MANAGE_STRUCTURE_IMPORT_URLS);
/* ADVANCED */
@@ -10,7 +10,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -18,16 +17,18 @@ import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.sap.sailing.domain.common.RankingMetrics;
@@ -49,7 +50,7 @@ import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
public class StructureImportManagementPanel extends FlowPanel implements RegattaStructureProvider {
public class StructureImportManagementPanel extends SimplePanel implements RegattaStructureProvider {
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
@@ -59,7 +60,7 @@ public class StructureImportManagementPanel extends FlowPanel implements Regatta
private final BusyIndicator busyIndicator;
private TextBox jsonURLTextBox;
private TextBox eventIDTextBox;
private CaptionPanel regattaImportPanel;
private Button listRegattasButton;
private Button importDetailsButton;
private VerticalPanel editSeriesPanel;
@@ -105,7 +106,12 @@ public class StructureImportManagementPanel extends FlowPanel implements Regatta
this.regattaListComposite = new StructureImportListComposite(this.sailingService, new RegattaSelectionModel(
true), this.regattaRefresher, this, this.errorReporter, this.stringMessages);
regattaListComposite.ensureDebugId("RegattaListComposite");
createUI();
VerticalPanel mainPanel = new VerticalPanel();
setWidget(mainPanel);
mainPanel.setWidth("100%");
createUI(mainPanel);
regattaListComposite.addSelectionChangeHandler(new Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
@@ -116,12 +122,10 @@ public class StructureImportManagementPanel extends FlowPanel implements Regatta
regattaStructureGrid = new FlexTable();
}
private void createUI() {
private void createUI(VerticalPanel mainPanel) {
final Panel progressPanel = new FlowPanel();
progressPanel.add(busyIndicator);
Grid URLgrid = new Grid(2, 2);
Label eventIDLabel = new Label(stringMessages.event() + ":");
Label jsonURLLabel = new Label(stringMessages.jsonUrl() + ":");
eventIDTextBox = new TextBox();
eventIDTextBox.addChangeHandler(new ChangeHandler() {
@Override
@@ -161,33 +165,39 @@ public class StructureImportManagementPanel extends FlowPanel implements Regatta
listRegattasAndTheirStructures();
}
});
VerticalPanel vp = new VerticalPanel();
HorizontalPanel buttonPanel = new HorizontalPanel();
URLgrid.setWidget(0, 0, eventIDLabel);
URLgrid.setWidget(0, 1, eventIDTextBox);
URLgrid.setWidget(1, 0, jsonURLLabel);
URLgrid.setWidget(1, 1, jsonURLTextBox);
vp.add(URLgrid);
vp.add(buttonPanel);
buttonPanel.add(listRegattasButton);
buttonPanel.add(importDetailsButton);
Grid grid = new Grid(1, 1);
vp.add(grid);
Grid eventURLGrid = new Grid(3, 2);
eventURLGrid.setWidget(0, 0, new Label(stringMessages.manage2Sail() + " " + stringMessages.event() + " " + stringMessages.id() + ":"));
eventURLGrid.setWidget(0, 1, eventIDTextBox);
eventURLGrid.setWidget(1, 0, new Label(stringMessages.jsonUrl() + ":"));
eventURLGrid.setWidget(1, 1, jsonURLTextBox);
eventURLGrid.setWidget(2, 1, listRegattasButton);
mainPanel.add(progressPanel);
mainPanel.add(eventURLGrid);
regattaImportPanel = new CaptionPanel(stringMessages.manage2Sail() + " " + stringMessages.event());
mainPanel.add(regattaImportPanel);
VerticalPanel regattaImportContentPanel = new VerticalPanel();
regattaImportPanel.setContentWidget(regattaImportContentPanel);
grid.setWidget(0, 0, regattaListComposite);
grid.getRowFormatter().setVerticalAlign(0, HasVerticalAlignment.ALIGN_TOP);
grid.getColumnFormatter().getElement(0/** 1 */).getStyle().setPaddingTop(2.0, Unit.EM);
editSeriesPanel = new VerticalPanel();
add(progressPanel);
add(vp);
add(editSeriesPanel);
HorizontalPanel hPanel = new HorizontalPanel();
hPanel.setSpacing(10);
hPanel.add(regattaListComposite);
hPanel.setCellWidth(regattaListComposite, "50%");
hPanel.add(editSeriesPanel);
hPanel.setCellWidth(editSeriesPanel, "50%");
regattaImportContentPanel.add(hPanel);
regattaImportContentPanel.add(importDetailsButton);
}
/**
* Adds an event selector and a "create new event" button to the {@link #editSeriesPanel} in its first row
*/
private void createEventSelectionAndCreateEventButtonUI() {
private Widget createEventSelectionAndCreateEventButtonUI() {
Grid grid = new Grid(1, 2);
sailingEventsListBox = new ListBox();
sailingEventsListBox.setMultipleSelect(false);
@@ -223,7 +233,7 @@ public class StructureImportManagementPanel extends FlowPanel implements Regatta
}
}
});
return grid;
}
private void openEventCreateDialog() {
@@ -11,6 +11,7 @@ import com.sap.sse.gwt.client.DefaultRule_1_0n;
public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, com.sap.sse.gwt.adminconsole.StringMessages {
public static final StringMessages INSTANCE = GWT.create(StringMessages.class);
String manage2Sail();
String tracTracEvents();
String swissTimingEvents();
String trackedBefore();
@@ -1164,7 +1165,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
@Override
String errorCommunicatingWithServer();
String userManagement();
String structureImportUrls();
String regattaStructureImport();
String filteredBy();
String filterBy();
String editSeries();
@@ -1,3 +1,4 @@
manage2Sail=Manage2Sail
tracTracEvents=TracTrac Events
swissTimingEvents=SwissTiming Events
trackedBefore=History of tracked events
@@ -1134,7 +1135,7 @@ remoteProcedureCall=Remote Procedure Call
serverReplies=Server replies
errorCommunicatingWithServer=Error communicating with server
userManagement=User Management
structureImportUrls=Regatta Structure Import
regattaStructureImport=Regatta Structure Import
filteredBy=filtered by
editSeries=Edit Series
pleaseSelectAtLeastOneRegatta=Please select at least one regatta
@@ -1,3 +1,4 @@
manage2Sail=Manage2Sail
createNewEvent=Create New EventtracTracEvents=TracTrac Events
swissTimingEvents=SwissTiming Events
trackedBefore=Historie verfolgter Events
@@ -1128,7 +1129,7 @@ remoteProcedureCall=Entfernter Prozeduraufruf
serverReplies=Server antwortet
errorCommunicatingWithServer=Fehler bei der Kommunikation mit dem Server
userManagement=Benutzerverwaltung
structureImportUrls=Regattastruktur-Import
regattaStructureImport=Regattastruktur-Import
editSeries=Serie bearbeiten
filteredBy=gefiltert nach
pleaseSelectAtLeastOneRegatta=Bitte wenigstens eine Regatta auswählen
@@ -1,4 +1,5 @@
# If you want new properties translated then sent this over GMR (Mark Angell <mangell@gmr.com>)
manage2Sail=Manage2Sail
tracTracEvents=События Трак Трак
swissTimingEvents=События Swiss Timing
trackedBefore=Ранее Отслеженные
@@ -1076,7 +1077,7 @@ remoteProcedureCall=Remote Procedure Call
serverReplies=Server replies
errorCommunicatingWithServer=Error communicating with server
userManagement=User Management
structureImportUrls=Regatta structure import
regattaStructureImport=Regatta structure import
editSeries=Edit Series
filteredBy=filtered by
pleaseSelectAtLeastOneRegatta=Please select at least one regatta
@@ -1,3 +1,4 @@
manage2Sail=Manage2Sail
enableRaceFilter=Enable filter
finishLine=终点线
raceLabel=比赛轮次
@@ -460,7 +461,7 @@ createFlexibleLeaderboard=Create flexible leaderboard
unknown=Unknown
furtherSignalsAshore=Further signals ashore
pleaseSelectAtLeastOneRegatta=Please select at least one regatta
structureImportUrls=Regatta Structure Import
regattaStructureImport=Regatta Structure Import
raceAbandoned=放弃
sheetName=Sheet name
rrs26Start=RRS26 start
@@ -56,6 +56,7 @@ public class RaceContext {
private final RaceLog raceLog;
private final ReadonlyRaceState state;
private final Event event;
private final long TIME_BEFORE_START_TO_SHOW_RACES_AS_LIVE = 15 * 60 * 1000; // 15 min
private final long TIME_TO_SHOW_CANCELED_RACES_AS_LIVE = 5 * 60 * 1000; // 5 min
public RaceContext(Event event, Leaderboard leaderboard, RaceColumn raceColumn, Fleet fleet, RaceLogResolver raceLogResolver) {
@@ -308,7 +309,7 @@ public class RaceContext {
result = trackedRace.isLive(now);
} else {
// no data from tracking but maybe a manual setting of the start and finish time
TimePoint startOfLivePeriod = startTime.minus(TimingConstants.PRE_START_PHASE_DURATION_IN_MILLIS);
TimePoint startOfLivePeriod = startTime.minus(TIME_BEFORE_START_TO_SHOW_RACES_AS_LIVE);
TimePoint endOfLivePeriod = finishTime != null ? finishTime.plus(TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS) : null;
if(now.after(startOfLivePeriod) && (endOfLivePeriod == null || now.before(endOfLivePeriod))) {
result = true;
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.news.EventNewsItem;
import com.sap.sailing.news.EventNewsProvider;
import com.sap.sse.common.TimePoint;
@@ -28,20 +29,21 @@ public class LeaderboardUpdateEventNewsProvider implements EventNewsProvider {
Iterable<LeaderboardGroup> leaderboardGroups = event.getLeaderboardGroups();
for(LeaderboardGroup leaderboardGroup: leaderboardGroups) {
for(Leaderboard leaderboard: leaderboardGroup.getLeaderboards()) {
TimePoint timePointOfLatestModification = leaderboard.getTimePointOfLatestModification();
if(timePointOfLatestModification == null) {
continue;
}
String displayName = leaderboard.getDisplayName() != null ?leaderboard.getDisplayName() :leaderboard.getName();
String boatClassName= null;
if(leaderboard instanceof RegattaLeaderboard) {
BoatClass boatClass = ((RegattaLeaderboard) leaderboard).getRegatta().getBoatClass();
if(boatClass != null) {
boatClassName = boatClass.getDisplayName();
SettableScoreCorrection scoreCorrection = leaderboard.getScoreCorrection();
if(scoreCorrection != null) {
TimePoint timePointOfLatestModification = scoreCorrection.getTimePointOfLastCorrectionsValidity();
if(timePointOfLatestModification != null) {
String displayName = leaderboard.getDisplayName() != null ?leaderboard.getDisplayName() :leaderboard.getName();
String boatClassName= null;
if(leaderboard instanceof RegattaLeaderboard) {
BoatClass boatClass = ((RegattaLeaderboard) leaderboard).getRegatta().getBoatClass();
if(boatClass != null) {
boatClassName = boatClass.getDisplayName();
}
}
result.add(new LeaderboardUpdateNewsItem(event.getId(), timePointOfLatestModification.asDate(), leaderboard.getName(), displayName, boatClassName));
}
}
result.add(new LeaderboardUpdateNewsItem(event.getId(), timePointOfLatestModification.asDate(), leaderboard.getName(), displayName, boatClassName));
}
}
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.polars.PolarsChangedListener;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.polars.aggregation.PolarFixAggregator;
import com.sap.sailing.polars.aggregation.SimplePolarFixRaceInterval;
@@ -206,4 +207,14 @@ public class PolarDataServiceImpl implements PolarDataService {
}
}
@Override
public void registerListener(BoatClass boatClass, PolarsChangedListener listener) {
polarDataMiner.registerListener(boatClass, listener);
}
@Override
public void unregisterListener(BoatClass boatClass, PolarsChangedListener listener) {
polarDataMiner.unregisterListener(boatClass, listener);
}
}
@@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
@@ -14,6 +15,7 @@ import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.Tack;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarsChangedListener;
import com.sap.sse.datamining.AdditionalResultDataBuilder;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.factories.GroupKeyFactory;
@@ -25,7 +27,13 @@ public class CubicRegressionPerCourseProcessor implements Processor<GroupedDataE
private static final Logger logger = Logger.getLogger(CubicRegressionPerCourseProcessor.class.getName());
private final Map<GroupKey, AngleAndSpeedRegression> regressions = new HashMap<>();
private ConcurrentHashMap<BoatClass, Set<PolarsChangedListener>> listeners;
public CubicRegressionPerCourseProcessor(ConcurrentHashMap<BoatClass, Set<PolarsChangedListener>> listeners) {
this.listeners = listeners;
}
@Override
public boolean canProcessElements() {
// TODO Auto-generated method stub
@@ -46,6 +54,12 @@ public class CubicRegressionPerCourseProcessor implements Processor<GroupedDataE
}
}
regression.addData(fix.getWind(), fix.getAbsoluteAngleToTheWind(), fix.getBoatSpeed());
Set<PolarsChangedListener> listenersForBoatClass = listeners.get(fix.getBoatClass());
if (listenersForBoatClass != null) {
for (PolarsChangedListener listener : listenersForBoatClass) {
listener.polarsChanged();
}
}
}
}
@@ -3,11 +3,13 @@ package com.sap.sailing.polars.mining;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
@@ -40,6 +42,7 @@ import com.sap.sailing.domain.common.impl.PolarSheetsHistogramDataImpl;
import com.sap.sailing.domain.common.impl.WindSpeedSteppingWithMaxDistance;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarsChangedListener;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.polars.impl.CubicEquation;
import com.sap.sse.datamining.components.FilterCriterion;
@@ -64,6 +67,8 @@ public class PolarDataMiner {
private final Queue<GPSFixMovingWithOriginInfo> fixQueue = new ConcurrentLinkedQueue<GPSFixMovingWithOriginInfo>();
private static final Logger logger = Logger.getLogger(PolarDataMiner.class.getSimpleName());
private final ConcurrentHashMap<BoatClass, Set<PolarsChangedListener>> listeners = new ConcurrentHashMap<>();
private ThreadPoolExecutor createExecutor() {
return new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS,
@@ -135,7 +140,7 @@ public class PolarDataMiner {
GPSFixMovingWithPolarContext.class, executor, movingAverageGrouperResultReceivers, parameterizedDimensions);
cubicRegressionPerCourseProcessor = new CubicRegressionPerCourseProcessor();
cubicRegressionPerCourseProcessor = new CubicRegressionPerCourseProcessor(listeners);
Collection<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>> regressionPerCourseGrouperResultReceivers = new ArrayList<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>>();
regressionPerCourseGrouperResultReceivers.add(cubicRegressionPerCourseProcessor);
@@ -147,7 +152,7 @@ public class PolarDataMiner {
GPSFixMovingWithPolarContext.class, executor, regressionPerCourseGrouperResultReceivers, parameterizedDimensionsForCubicRegression);
ClusterGroup<Bearing> angleClusterGroup = createAngleClusterGroup();
speedRegressionPerAngleClusterProcessor = new SpeedRegressionPerAngleClusterProcessor(angleClusterGroup);
speedRegressionPerAngleClusterProcessor = new SpeedRegressionPerAngleClusterProcessor(angleClusterGroup, listeners);
Collection<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>> regressionPerAngleClusterGrouperResultReceivers = new ArrayList<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>>();
regressionPerAngleClusterGrouperResultReceivers.add(speedRegressionPerAngleClusterProcessor);
@@ -436,4 +441,21 @@ public class PolarDataMiner {
}
}
}
public void registerListener(BoatClass boatClass, PolarsChangedListener listener) {
Set<PolarsChangedListener> listenersForBoatClass = listeners.get(boatClass);
if (listenersForBoatClass == null) {
Map<PolarsChangedListener, Boolean> mapForConcurrency = new ConcurrentHashMap<>();
listenersForBoatClass = Collections.newSetFromMap(mapForConcurrency);
listeners.put(boatClass, listenersForBoatClass);
}
listenersForBoatClass.add(listener);
}
public void unregisterListener(BoatClass boatClass, PolarsChangedListener listener) {
Set<PolarsChangedListener> listenersForBoatClass = listeners.get(boatClass);
if (listenersForBoatClass != null) {
listenersForBoatClass.remove(listener);
}
}
}
@@ -2,6 +2,8 @@ package com.sap.sailing.polars.mining;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
@@ -14,6 +16,7 @@ import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarsChangedListener;
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
import com.sap.sse.datamining.AdditionalResultDataBuilder;
@@ -33,9 +36,12 @@ public class SpeedRegressionPerAngleClusterProcessor implements Processor<Groupe
private final Map<BoatClass, Long> fixCountPerBoatClass = new HashMap<>();
private final ClusterGroup<Bearing> angleClusterGroup;
private final ConcurrentHashMap<BoatClass, Set<PolarsChangedListener>> listeners;
public SpeedRegressionPerAngleClusterProcessor(ClusterGroup<Bearing> angleClusterGroup) {
public SpeedRegressionPerAngleClusterProcessor(ClusterGroup<Bearing> angleClusterGroup, ConcurrentHashMap<BoatClass, Set<PolarsChangedListener>> listeners) {
this.angleClusterGroup = angleClusterGroup;
this.listeners = listeners;
}
@Override
@@ -64,6 +70,12 @@ public class SpeedRegressionPerAngleClusterProcessor implements Processor<Groupe
}
GPSFixMovingWithPolarContext fix = element.getDataEntry();
regression.addData(fix.getWind().getObject().getKnots(), fix.getBoatSpeed().getObject().getKnots());
Set<PolarsChangedListener> listenersForBoatClass = listeners.get(fix.getBoatClass());
if (listenersForBoatClass != null) {
for (PolarsChangedListener listener : listenersForBoatClass) {
listener.polarsChanged();
}
}
}
/**
@@ -1,32 +1,32 @@
<?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"/>
<stringAttribute key="configLocation" value="${workspace_loc}/target"/>
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="true"/>
<intAttribute key="default_start_level" value="4"/>
<booleanAttribute key="includeOptional" value="true"/>
<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="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.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="-Djetty.port=8889 -Dreplication.exchangeName=sapsailinganalytics-replica -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2011 -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 -XX:+UseMembar -Dmongo.dbName=replica"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<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.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@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.logging@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.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@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.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@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.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.googlecode.mgwt@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.dashboards.gwt@5:true,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:default,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.news@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.polars@4:true,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@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.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sailing.xrr.schema@default:default,com.sap.sailing.xrr.structureimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.filestorage@default:default,com.sap.sse.gwt.adminconsole@default:default,com.sap.sse.gwt@default:default,com.sap.sse.mail@4:true,com.sap.sse.mongodb@default:default,com.sap.sse.operationaltransformation@default:default,com.sap.sse.replication@4:true,com.sap.sse.security.common@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security@5:true,com.sap.sse.shared.android@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"/>
<stringAttribute key="yk-options" value="&#13;&#10;additional-options2=onexit\=snapshot&#13;&#10;"/>
</launchConfiguration>
<?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"/>
<stringAttribute key="configLocation" value="${workspace_loc}/target"/>
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="true"/>
<intAttribute key="default_start_level" value="4"/>
<booleanAttribute key="includeOptional" value="true"/>
<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="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.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="-Djetty.port=8889 -Dreplication.exchangeName=sapsailinganalytics-replica -Declipse.ignoreApp=true -Dosgi.noShutdown=true&#13;&#10;-Dexpedition.udp.port=2011 -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 -XX:+UseMembar -Dmongo.dbName=replica"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<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.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@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.logging@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.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@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.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@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.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.googlecode.mgwt@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.dashboards.gwt@5:true,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:default,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.news@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.polars@4:true,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@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.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sailing.xrr.schema@default:default,com.sap.sailing.xrr.structureimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.filestorage@default:default,com.sap.sse.gwt.adminconsole@default:default,com.sap.sse.gwt.theme@default:default,com.sap.sse.gwt@default:default,com.sap.sse.mail@4:true,com.sap.sse.mongodb@default:default,com.sap.sse.operationaltransformation@default:default,com.sap.sse.replication@4:true,com.sap.sse.security.common@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security@5:true,com.sap.sse.shared.android@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"/>
<stringAttribute key="yk-options" value="&#13;&#10;additional-options2=onexit\=snapshot&#13;&#10;"/>
</launchConfiguration>
@@ -1,31 +1,31 @@
<?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"/>
<stringAttribute key="configLocation" value="${workspace_loc}/target"/>
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="true"/>
<intAttribute key="default_start_level" value="4"/>
<booleanAttribute key="includeOptional" value="true"/>
<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/jre1.8.0_20"/>
<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="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y -ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=2010 -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 -Digtimi.client.id=7fcdd217e0aa16090edb4ad55b09ec43b2021090e209541fc9b7003c2a2b70c6 -Digtimi.client.secret=aa569cf4909bdc7b0e04b11873f3c4ea20687421e010fcc25b771cca9e6f3f9a -Digtimi.client.redirecturi=http://127.0.0.1:8888/igtimi/oauth/v1/authorizationcallback -DspatialWind=true -Dmongo.host=172.31.25.253 -Dmongo.port=10200 -Dmongo.dbName=LOAD_TEST"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<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.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@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.logging@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.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@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.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@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.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.googlecode.mgwt@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.dashboards.gwt@5:true,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:default,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.news@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.polars@4:true,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@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.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sailing.xrr.schema@default:default,com.sap.sailing.xrr.structureimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.filestorage@default:default,com.sap.sse.gwt.adminconsole@default:default,com.sap.sse.gwt.theme@5:true,com.sap.sse.gwt@default:default,com.sap.sse.mail@4:true,com.sap.sse.mongodb@default:default,com.sap.sse.operationaltransformation@default:default,com.sap.sse.replication@4:true,com.sap.sse.security.common@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security@5:true,com.sap.sse.shared.android@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"/>
</launchConfiguration>
<?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"/>
<stringAttribute key="configLocation" value="${workspace_loc}/target"/>
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="true"/>
<intAttribute key="default_start_level" value="4"/>
<booleanAttribute key="includeOptional" value="true"/>
<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/sapjvm_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="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y -ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=2010 -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 -Digtimi.client.id=7fcdd217e0aa16090edb4ad55b09ec43b2021090e209541fc9b7003c2a2b70c6 -Digtimi.client.secret=aa569cf4909bdc7b0e04b11873f3c4ea20687421e010fcc25b771cca9e6f3f9a -Digtimi.client.redirecturi=http://127.0.0.1:8888/igtimi/oauth/v1/authorizationcallback"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/>
<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.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.rabbitmq.client@default:default,com.sun.jersey.contribs.jersey-multipart@default:default,com.sun.jersey@default:default,com.sun.mail.javax.mail@default:default,jackson-core-lgpl@default:default,jackson-jaxrs@default:default,jackson-mapper-lgpl@default:default,javax.servlet@default:default,javax.validation@default:default,javax.ws.rs@default:default,jcl.over.slf4j@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.logging@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.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@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.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.osgi.boot@3:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.jdom@default:default,org.jvnet.mimepull@default:default,org.mongodb.mongo-java-driver@default:default,org.objectweb.asm@default:default,rome@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.osgi@default:default,com.googlecode.java-diff-utils@default:default,com.googlecode.mgwt@default:default,com.sap.sailing.barbados.resultimport@default:default,com.sap.sailing.dashboards.gwt@5:true,com.sap.sailing.datamining.shared@default:default,com.sap.sailing.datamining@default:default,com.sap.sailing.declination@default:default,com.sap.sailing.domain.common@default:default,com.sap.sailing.domain.deckmanadapter@4:true,com.sap.sailing.domain.igtimiadapter.persistence@default:default,com.sap.sailing.domain.igtimiadapter@default:default,com.sap.sailing.domain.persistence@default:default,com.sap.sailing.domain.racelogtrackingadapter@3:default,com.sap.sailing.domain.shared.android@default:default,com.sap.sailing.domain.swisstimingadapter.persistence@default:default,com.sap.sailing.domain.swisstimingadapter@4:true,com.sap.sailing.domain.swisstimingreplayadapter@4:true,com.sap.sailing.domain.tractracadapter.persistence@default:default,com.sap.sailing.domain.tractracadapter@4:true,com.sap.sailing.domain@default:default,com.sap.sailing.ess40.resultimport@default:default,com.sap.sailing.expeditionconnector@default:default,com.sap.sailing.freg.resultimport@default:default,com.sap.sailing.geocoding@default:default,com.sap.sailing.gwt.ui@5:true,com.sap.sailing.kiworesultimport@default:default,com.sap.sailing.manage2sail.resultimport@default:default,com.sap.sailing.manage2sail@default:default,com.sap.sailing.news@default:default,com.sap.sailing.nmeaconnector@default:default,com.sap.sailing.polars@4:true,com.sap.sailing.resultimport@default:default,com.sap.sailing.sailwave.resultimport@default:default,com.sap.sailing.server.gateway.ess40@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.trackfiles@default:default,com.sap.sailing.server@default:default,com.sap.sailing.simulator@default:default,com.sap.sailing.udpconnector@default:default,com.sap.sailing.velum.resultimport@default:default,com.sap.sailing.www.events@4:true,com.sap.sailing.www@4:true,com.sap.sailing.xrr.resultimport@default:default,com.sap.sailing.xrr.schema@default:default,com.sap.sailing.xrr.structureimport@default:default,com.sap.sse.common@default:default,com.sap.sse.datamining.shared@default:default,com.sap.sse.datamining@default:default,com.sap.sse.filestorage@default:default,com.sap.sse.gwt.adminconsole@default:default,com.sap.sse.gwt.theme@5:true,com.sap.sse.gwt@default:default,com.sap.sse.mail@4:true,com.sap.sse.mongodb@default:default,com.sap.sse.operationaltransformation@default:default,com.sap.sse.replication@4:true,com.sap.sse.security.common@default:default,com.sap.sse.security.ui@6:true,com.sap.sse.security.userstore.mongodb@4:true,com.sap.sse.security@5:true,com.sap.sse.shared.android@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"/>
</launchConfiguration>
@@ -88,6 +88,7 @@ import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.RemoteSailingServerReferenceImpl;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
@@ -2374,13 +2375,6 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
public void serializeForInitialReplicationInternal(ObjectOutputStream oos) throws IOException {
StringBuffer logoutput = new StringBuffer();
logger.info("Serializing events...");
oos.writeObject(eventsById);
logoutput.append("\nSerialized " + eventsById.size() + " events\n");
for (Event event : eventsById.values()) {
logoutput.append(String.format("%3s\n", event.toString()));
}
logger.info("Serializing regattas...");
oos.writeObject(regattasByName);
logoutput.append("Serialized " + regattasByName.size() + " regattas\n");
@@ -2388,6 +2382,13 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
logoutput.append(String.format("%3s\n", regatta.toString()));
}
logger.info("Serializing events...");
oos.writeObject(eventsById);
logoutput.append("\nSerialized " + eventsById.size() + " events\n");
for (Event event : eventsById.values()) {
logoutput.append(String.format("%3s\n", event.toString()));
}
logger.info("Serializing regattas observed...");
oos.writeObject(regattasObservedForDefaultLeaderboard);
logger.info("Serializing regatta tracking cache...");
@@ -2441,13 +2442,6 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
// de-serialization; this will cause all classes to be visible that this bundle
// (com.sap.sailing.server) can see
StringBuffer logoutput = new StringBuffer();
logger.info("Reading all events...");
eventsById.putAll((Map<Serializable, Event>) ois.readObject());
logoutput.append("\nReceived " + eventsById.size() + " NEW events\n");
for (Event event : eventsById.values()) {
logoutput.append(String.format("%3s\n", event.toString()));
}
logger.info("Reading all regattas...");
regattasByName.putAll((Map<String, Regatta>) ois.readObject());
logoutput.append("Received " + regattasByName.size() + " NEW regattas\n");
@@ -2455,6 +2449,13 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
logoutput.append(String.format("%3s\n", regatta.toString()));
}
logger.info("Reading all events...");
eventsById.putAll((Map<Serializable, Event>) ois.readObject());
logoutput.append("\nReceived " + eventsById.size() + " NEW events\n");
for (Event event : eventsById.values()) {
logoutput.append(String.format("%3s\n", event.toString()));
}
// it is important that the leaderboards and tracked regattas are cleared before auto-linking to
// old leaderboards takes place which then don't match the new ones
logger.info("Reading all dynamic tracked regattas...");
@@ -2504,6 +2505,9 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
logger.info("Reading competitors...");
for (Competitor competitor : ((CompetitorStore) ois.readObject()).getCompetitors()) {
DynamicCompetitor dynamicCompetitor = (DynamicCompetitor) competitor;
// the following should actually be redundant because during de-serialization the Competitor objects,
// whose classes implement IsManagedByCache, should already have been got/created from/in the
// competitor store
competitorStore.getOrCreateCompetitor(dynamicCompetitor.getId(), dynamicCompetitor.getName(),
dynamicCompetitor.getColor(), dynamicCompetitor.getEmail(), dynamicCompetitor.getFlagImage(),
dynamicCompetitor.getTeam(), dynamicCompetitor.getBoat(), dynamicCompetitor.getTimeOnTimeFactor(),
@@ -3218,9 +3222,13 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
public Iterable<Competitor> getCompetitorInOrderOfWindwardDistanceTraveledFarthestFirst(TrackedRace trackedRace, TimePoint timePoint) {
final RankingInfo rankingInfo = trackedRace.getRankingMetric().getRankingInfo(timePoint);
final List<Competitor> result = new ArrayList<>();
Util.addAll(trackedRace.getRace().getCompetitors(), result);
result.sort((c1, c2) -> rankingInfo.getCompetitorRankingInfo().apply(c2).getWindwardDistanceSailed().compareTo(
rankingInfo.getCompetitorRankingInfo().apply(c1).getWindwardDistanceSailed()));
final Map<Competitor, Distance> windwardDistanceSailedPerCompetitor = new HashMap<>();
for (final Competitor competitor : trackedRace.getRace().getCompetitors()) {
result.add(competitor);
windwardDistanceSailedPerCompetitor.put(competitor, rankingInfo.getCompetitorRankingInfo().apply(competitor).getWindwardDistanceSailed());
}
result.sort((c1, c2) -> windwardDistanceSailedPerCompetitor.get(c2).compareTo(
windwardDistanceSailedPerCompetitor.get(c1)));
return result;
}
@@ -379,9 +379,13 @@ public class SimulationServiceImpl implements SimulationService {
// determine legtype upwind/downwind/reaching
LegType legType = null;
try {
legType = trackedRace.getTrackedLeg(leg).getLegType(startTimePoint);
} catch (NoWindException e) {
if (startTimePoint != null) {
try {
legType = trackedRace.getTrackedLeg(leg).getLegType(startTimePoint);
} catch (NoWindException e) {
return null;
}
} else {
return null;
}
@@ -816,15 +816,15 @@ public class PolarDiagramBase implements PolarDiagram, Serializable {
@Override
public int compare(Bearing o1, Bearing o2) {
Double d1 = o1.getDegrees();
double d1 = o1.getDegrees();
if (d1 < 0) {
d1 = 360 + d1;
}
Double d2 = o2.getDegrees();
double d2 = o2.getDegrees();
if (d2 < 0) {
d2 = 360 + d2;
}
return d1.compareTo(d2);
return d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
}
};
@@ -0,0 +1,8 @@
package com.sap.sse.util;
import java.io.Serializable;
import java.util.function.Function;
public interface SerializableFunction<T, R> extends Function<T, R>, Serializable {
}
@@ -286,7 +286,7 @@ public class MessageSendingService extends Service implements MessageSendingList
int resendMillis = PrefUtils.getInt(this, R.string.preference_messageResendIntervalMillis_key,
R.integer.preference_messageResendIntervalMillis_default);
if (!success) {
ExLog.i(this, "MS", "success");
ExLog.i(this, "MS", "!success");
reportApiConnectivity(APIConnectivity.transmissionError);
ExLog.w(this, TAG, "Error while posting intent to server. Will persist intent...");
try {
@@ -302,7 +302,7 @@ public class MessageSendingService extends Service implements MessageSendingList
reportUnsentGPSFixesCount();
serviceLogger.onMessageSentFailed();
} else {
ExLog.i(this, "MS", "!success");
ExLog.i(this, "MS", "success");
reportApiConnectivity(APIConnectivity.transmissionSuccess);
ExLog.i(this, TAG, "Message successfully sent.");
if (persistenceManager.areIntentsDelayed()) {
@@ -1,5 +1,7 @@
package com.sap.sailing.android.buoy.positioning.app.ui.fragments;
import java.text.DecimalFormat;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
@@ -23,14 +25,15 @@ import com.sap.sailing.android.buoy.positioning.app.util.PingHelper;
import com.sap.sailing.android.buoy.positioning.app.valueobjects.MarkInfo;
import com.sap.sailing.android.buoy.positioning.app.valueobjects.MarkPingInfo;
import com.sap.sailing.android.shared.data.LeaderboardInfo;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.ui.customviews.OpenSansButton;
import com.sap.sailing.android.shared.ui.customviews.OpenSansTextView;
import com.sap.sailing.android.shared.ui.customviews.SignalQualityIndicatorView;
import com.sap.sailing.android.ui.fragments.BaseFragment;
import java.text.DecimalFormat;
public class BuoyFragment extends BaseFragment implements LocationListener {
private static final int GPS_MIN_DISTANCE = 1;
private static final int GPS_MIN_TIME = 1000;
private OpenSansTextView markHeaderTextView;
private OpenSansTextView latitudeTextView;
private OpenSansTextView longitudeTextView;
@@ -80,7 +83,7 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
signalQualityIndicatorView.setSignalQuality(GPSQuality.noSignal.toInt());
if (mark != null) {
markHeaderTextView.setText(mark.getName());
setUpTextUI(null);
setUpTextUI(lastKnownLocation);
GoogleMap map = mapFragment.getMap();
configureMap(map);
updateMap();
@@ -124,6 +127,11 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
accuracyText += " (" + String.format(accuracyString, accuracyFormatter.format(markPing.getAccuracy()))
+ ")";
}
ExLog.w(getActivity(), getTag(), "Setting latitude to: "+latitudeText);
ExLog.w(getActivity(), getTag(), "Setting longitude to: "+longitudeText);
ExLog.w(getActivity(), getTag(), "Setting accuracy to: "+accuracyText);
latitudeTextView.setText(latitudeText);
longitudeTextView.setText(longitudeText);
accuracyTextView.setText(accuracyText);
@@ -179,7 +187,13 @@ public class BuoyFragment extends BaseFragment implements LocationListener {
private void initLocationProvider() {
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10, this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_MIN_TIME, GPS_MIN_DISTANCE, this);
Location initialLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (initialLocation != null) {
onLocationChanged(initialLocation);
}
}
public void updateMap() {
+8 -3
View File
@@ -3,22 +3,27 @@
## Server Landscape
We run four servers for the event:
- on EC2: **Master 1**, **Master 2**, **Replica 1** and **Replica 2** with an **ELB** in front,
- on EC2: **Master 1**, **Master 2**, **Master 3**, **Replica 1** and **Replica 2** with an **ELB** in front,
- ELB canonical name is KW2015-553831863.eu-west-1.elb.amazonaws.com
- locally: **Cube-Server**
for fast and available switching. The DB they use is called `KW2015`, and so is the replication channel. The git branch we use to merge the features we want to deploy to the event servers is called `kielerwoche2015` and the git tag used to build a release for it is called `kielerwoche2015-release`. See http://hudson.sapsailing.com/job/SAPSailingAnalytics-kielerwoche2015/ and http://hudson.sapsailing.com/job/SAPSailingAnalytics-kielerwoche2015-release/, respectively, for their Hudson jobs.
### Master 1 Server
### Master 1 Server (32GB)
- Admin Console at http://ec2-54-154-151-10.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.154.151.10
- Internal IP: 172.31.24.187
### Master 2 Server
### Master 2 Server (32GB)
- Admin Console at http://ec2-54-76-169-213.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.76.169.213
- Internal IP: 172.31.30.73
### Master 3 Server (64GB)
- Admin Console at http://ec2-54-171-148-10.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
- External IP: 54.171.148.10
- Internal IP: 172.31.26.119
### "Current" Master
Whichever master is current, we map the main Apache URL http://kielerwoche2015-master.sapsailing.com to it. This is also the URL to use for Tablet and Smartphone configurations.