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

This commit is contained in:
Nidhi Sawhney committed 2012-04-22 16:27:21 +02:00
commit 698ada3fb1
122 files changed
+1314 -433

No files matched your search

@@ -3,6 +3,8 @@ package com.sap.sailing.domain.common;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
public abstract class AbstractBearing implements Bearing { public abstract class AbstractBearing implements Bearing {
private static final long serialVersionUID = 1968420344627864784L;
@Override @Override
public Bearing reverse() { public Bearing reverse() {
if (getDegrees() >= 180) { if (getDegrees() >= 180) {
@@ -4,6 +4,8 @@ import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl;
public abstract class AbstractDistance implements Distance { public abstract class AbstractDistance implements Distance {
private static final long serialVersionUID = 4393500221539639333L;
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
return (o instanceof Distance) && this.compareTo((Distance) o) == 0; return (o instanceof Distance) && this.compareTo((Distance) o) == 0;
@@ -4,6 +4,8 @@ import com.sap.sailing.domain.common.impl.NauticalMileDistance;
public abstract class AbstractSpeedImpl implements Speed { public abstract class AbstractSpeedImpl implements Speed {
private static final long serialVersionUID = 4910662213901175982L;
@Override @Override
public double getBeaufort() { public double getBeaufort() {
return Math.exp(Math.log(getKnots()*1.852/3.6 / 0.8360)*2/3); return Math.exp(Math.log(getKnots()*1.852/3.6 / 0.8360)*2/3);
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.common; package com.sap.sailing.domain.common;
public interface Bearing { import java.io.Serializable;
public interface Bearing extends Serializable {
double getDegrees(); double getDegrees();
@@ -10,8 +10,8 @@ import java.io.Serializable;
* *
*/ */
public enum DetailType implements Serializable { public enum DetailType implements Serializable {
DISTANCE_TRAVELED(0), AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2), RANK_GAIN(0), NUMBER_OF_MANEUVERS(0), CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2), DISTANCE_TRAVELED(0), AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2), RACE_RANK(0), RANK_GAIN(0), NUMBER_OF_MANEUVERS(0),
ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1), VELOCITY_MADE_GOOD_IN_KNOTS(2), GAP_TO_LEADER_IN_SECONDS(0), CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2), ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1), VELOCITY_MADE_GOOD_IN_KNOTS(2), GAP_TO_LEADER_IN_SECONDS(0),
WINDWARD_DISTANCE_TO_GO_IN_METERS(0), RACE_DISTANCE_TRAVELED(0), RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2), RACE_GAP_TO_LEADER_IN_SECONDS(0), WINDWARD_DISTANCE_TO_GO_IN_METERS(0), RACE_DISTANCE_TRAVELED(0), RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2), RACE_GAP_TO_LEADER_IN_SECONDS(0),
RACE_DISTANCE_TO_LEADER_IN_METERS(0), RACE_DISTANCE_TO_LEADER_IN_METERS(0),
WINDWARD_DISTANCE_TO_OVERALL_LEADER(0), HEAD_UP(0), BEAR_AWAY(0), TACK(0), JIBE(0), PENALTY_CIRCLE(0), MARK_PASSING(0), CURRENT_LEG(0), WINDWARD_DISTANCE_TO_OVERALL_LEADER(0), HEAD_UP(0), BEAR_AWAY(0), TACK(0), JIBE(0), PENALTY_CIRCLE(0), MARK_PASSING(0), CURRENT_LEG(0),
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.common; package com.sap.sailing.domain.common;
import java.io.Serializable;
/** /**
@@ -8,8 +10,10 @@ package com.sap.sailing.domain.common;
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
* *
*/ */
public interface Distance extends Comparable<Distance> { public interface Distance extends Comparable<Distance>, Serializable {
static final Distance NULL = new Distance() { static final Distance NULL = new Distance() {
private static final long serialVersionUID = -3167560884686340893L;
@Override @Override
public int compareTo(Distance o) { public int compareTo(Distance o) {
return getMeters() > o.getMeters() ? 1 : getMeters() == o.getMeters() ? 0 : -1; return getMeters() > o.getMeters() ? 1 : getMeters() == o.getMeters() ? 0 : -1;
@@ -0,0 +1,29 @@
package com.sap.sailing.domain.common;
/**
* The reasons why a competitor may get the maximum number of points, usually equaling the
* number of competitors enlisted for the regatta plus one.
*
* @author Axel Uhl (d043530)
*
*/
public enum MaxPointsReason {
/** The competitor finished the race properly */
NONE,
/** Did Not Start */
DNS,
/** Did Not Finish */
DNF,
/** DiSQualified */
DSQ,
/** On Course Side (jumped the gun) */
OCS,
/** Disqualified, non-discardable */
DND,
/** Black Flag Disqualified */
BFD,
/** Did Not Compete */
DNC,
/** Retired After Finishing */
RAF
}
@@ -1,13 +1,17 @@
package com.sap.sailing.domain.common; package com.sap.sailing.domain.common;
import java.io.Serializable;
/** /**
* A speed, convertable in various units of measure. Can be negative. * A speed, convertable in various units of measure. Can be negative.
* *
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
* *
*/ */
public interface Speed extends Comparable<Speed> { public interface Speed extends Comparable<Speed>, Serializable {
final static Speed NULL = new Speed() { final static Speed NULL = new Speed() {
private static final long serialVersionUID = 1448378212070589610L;
@Override @Override
public int compareTo(Speed o) { public int compareTo(Speed o) {
return getMetersPerSecond() > o.getMetersPerSecond() ? 1 : getMetersPerSecond() == o.getMetersPerSecond() ? 0 : -1; return getMetersPerSecond() > o.getMetersPerSecond() ? 1 : getMetersPerSecond() == o.getMetersPerSecond() ? 0 : -1;
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.Mile; import com.sap.sailing.domain.common.Mile;
public class CentralAngleDistance extends AbstractDistance { public class CentralAngleDistance extends AbstractDistance {
private static final long serialVersionUID = -388639688376644968L;
private final double centralAngleRad; private final double centralAngleRad;
public CentralAngleDistance(double centralAngleRad) { public CentralAngleDistance(double centralAngleRad) {
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.common.Bearing;
public class DegreeBearingImpl extends AbstractBearing implements Bearing { public class DegreeBearingImpl extends AbstractBearing implements Bearing {
private static final long serialVersionUID = -8045400378221073451L;
private final double bearingDeg; private final double bearingDeg;
/** /**
* *
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.common.Mile;
import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.Speed;
public class KilometersPerHourSpeedImpl extends AbstractSpeedImpl implements Speed { public class KilometersPerHourSpeedImpl extends AbstractSpeedImpl implements Speed {
private static final long serialVersionUID = -524654796500981303L;
private final double speedInKilometersPerHour; private final double speedInKilometersPerHour;
public KilometersPerHourSpeedImpl(double speedInKilometersPerHour) { public KilometersPerHourSpeedImpl(double speedInKilometersPerHour) {
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.common.AbstractDistance;
import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.Distance;
public class NauticalMileDistance extends AbstractDistance { public class NauticalMileDistance extends AbstractDistance {
private static final long serialVersionUID = 3771473789235934127L;
private final double nauticalMiles; private final double nauticalMiles;
public NauticalMileDistance(double nauticalMiles) { public NauticalMileDistance(double nauticalMiles) {
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.common.AbstractBearing;
import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Bearing;
public class RadianBearingImpl extends AbstractBearing implements Bearing { public class RadianBearingImpl extends AbstractBearing implements Bearing {
private static final long serialVersionUID = 5044142324540650696L;
private final double bearingRad; private final double bearingRad;
public RadianBearingImpl(double bearingRad) { public RadianBearingImpl(double bearingRad) {
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl; import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.EventNameAndRaceName; import com.sap.sailing.domain.common.EventNameAndRaceName;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
@@ -33,7 +34,6 @@ import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup; import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection; import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule; import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl; import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
@@ -5,9 +5,9 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection; import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule; import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardImpl; import com.sap.sailing.domain.leaderboard.impl.LeaderboardImpl;
@@ -15,13 +15,13 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.SpeedWithBearing; import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.Timed; import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup; import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection; import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.persistence.MongoObjectFactory; import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.tracking.Positioned; import com.sap.sailing.domain.tracking.Positioned;
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.tracking.TrackedEvent;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore; import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.mongodb.MongoDBService;
/** /**
* Stores wind tracks of sources that {@link WindSource#canBeStored() can be stored}. The {@link EmptyWindStore}'s * Stores wind tracks of sources that {@link WindSource#canBeStored() can be stored}. The {@link EmptyWindStore}'s
@@ -23,7 +24,8 @@ import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
* *
*/ */
public class MongoWindStoreImpl extends EmptyWindStore implements MongoWindStore { public class MongoWindStoreImpl extends EmptyWindStore implements MongoWindStore {
private final DB db; private static final long serialVersionUID = 5236931230924201642L;
private transient final DB db;
private final MongoObjectFactory mongoObjectFactory; private final MongoObjectFactory mongoObjectFactory;
private final DomainObjectFactory domainObjectFactory; private final DomainObjectFactory domainObjectFactory;
@@ -34,6 +36,14 @@ public class MongoWindStoreImpl extends EmptyWindStore implements MongoWindStore
this.domainObjectFactory = domainObjectFactory; this.domainObjectFactory = domainObjectFactory;
} }
/**
* Initializes the DB using the default instance {@link MongoDBService#getDB()}. Note that this
* won't preserve a change in database setups such as the use of a test database across serialization.
*/
private Object readResolve() throws UnknownHostException, MongoException {
return new MongoWindStoreImpl(MongoDBService.INSTANCE.getDB(), mongoObjectFactory, domainObjectFactory);
}
/** /**
* Loads the wind track from the database and adds a {@link MongoWindListener} listener such that * Loads the wind track from the database and adds a {@link MongoWindListener} listener such that
* additions to the wind track will be written to the MongoDB. * additions to the wind track will be written to the MongoDB.
@@ -94,7 +94,7 @@ public class DomainFactoryImpl implements DomainFactory {
public Event getOrCreateEvent(String raceID) { public Event getOrCreateEvent(String raceID) {
Event result = raceIDToEventCache.get(raceID); Event result = raceIDToEventCache.get(raceID);
if (result == null) { if (result == null) {
result = new EventImpl(raceID, getOrCreateBoatClassFromRaceID(raceID)); result = new EventImpl(raceID, null);
raceIDToEventCache.put(raceID, result); raceIDToEventCache.put(raceID, result);
} }
return result; return result;
@@ -86,6 +86,7 @@ public class ConfidenceTest {
private static class ScalableBearingWithConfidence<RelativeTo> extends ScalableBearing private static class ScalableBearingWithConfidence<RelativeTo> extends ScalableBearing
implements HasConfidenceAndIsScalable<ScalableBearing, Bearing, RelativeTo> { implements HasConfidenceAndIsScalable<ScalableBearing, Bearing, RelativeTo> {
private static final long serialVersionUID = 6609861367777720855L;
private final double confidence; private final double confidence;
private final RelativeTo relativeTo; private final RelativeTo relativeTo;
private final Bearing bearing; private final Bearing bearing;
@@ -22,13 +22,13 @@ import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.base.impl.NationalityImpl; import com.sap.sailing.domain.base.impl.NationalityImpl;
import com.sap.sailing.domain.base.impl.PersonImpl; import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.TeamImpl; import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardImpl; import com.sap.sailing.domain.leaderboard.impl.LeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl; import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl; import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.test.mock.MockedTrackedRace; import com.sap.sailing.domain.test.mock.MockedTrackedRace;
public class MockedTrackedRaceWithFixedRank extends MockedTrackedRace { public class MockedTrackedRaceWithFixedRank extends MockedTrackedRace {
private static final long serialVersionUID = -8587203762630194172L;
private final int rank; private final int rank;
private final boolean started; private final boolean started;
private final RaceDefinition raceDefinition; private final RaceDefinition raceDefinition;
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.RaceDefinition;
public class MockedTrackedRaceWithFixedRankAndManyCompetitors extends MockedTrackedRaceWithFixedRank { public class MockedTrackedRaceWithFixedRankAndManyCompetitors extends MockedTrackedRaceWithFixedRank {
private static final long serialVersionUID = -6189437610363552577L;
private final Set<Competitor> competitors; private final Set<Competitor> competitors;
private final RaceDefinition raceDefinition; private final RaceDefinition raceDefinition;
@@ -0,0 +1,90 @@
package com.sap.sailing.domain.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.GregorianCalendar;
import org.junit.Before;
import org.junit.Test;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.impl.WindImpl;
import com.sap.sailing.domain.tractracadapter.ReceiverType;
import com.sap.sailing.util.ObjectInputStreamWithConfigurableClassLoader;
public class SerializationTest extends OnlineTracTracBasedTest {
public SerializationTest() throws MalformedURLException, URISyntaxException {
super();
}
@Before
public void setUp() throws URISyntaxException, IOException, InterruptedException {
super.setUp();
super.setUp("event_20110609_KielerWoch",
/* raceId */"357c700a-9d9a-11e0-85be-406186cbf87c", new ReceiverType[] { ReceiverType.MARKPASSINGS,
ReceiverType.RACECOURSE, ReceiverType.RAWPOSITIONS });
OnlineTracTracBasedTest.fixApproximateMarkPositionsForWindReadOut(getTrackedRace(), new MillisecondsTimePoint(
new GregorianCalendar(2011, 05, 23).getTime()));
getTrackedRace().recordWind(
new WindImpl(/* position */null, MillisecondsTimePoint.now(), new KnotSpeedWithBearingImpl(12,
new DegreeBearingImpl(65))), new WindSourceImpl(WindSourceType.WEB));
}
private Pair<Integer, Long> getSerializationSizeAndTime(Serializable s) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
long start = System.currentTimeMillis();
new ObjectOutputStream(bos).writeObject(s);
return new Pair<Integer, Long>(bos.size(), System.currentTimeMillis()-start);
}
private <T extends Serializable> T cloneBySerialization(final T s) throws IOException, ClassNotFoundException {
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
final ObjectOutputStream dos = new ObjectOutputStream(pos);
new Thread("clone writer") {
public void run() {
try {
dos.writeObject(s);
dos.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}.start();
ObjectInputStream dis = new ObjectInputStreamWithConfigurableClassLoader(pis);
@SuppressWarnings("unchecked")
T result = (T) dis.readObject();
dis.close();
return result;
}
@Test
public void testSerializingGPSTrack() throws ClassNotFoundException, IOException {
DynamicGPSFixTrack<Competitor, GPSFixMoving> findelsTrack = getTrackedRace().getTrack(getCompetitorByName("Findel"));
DynamicGPSFixTrack<Competitor, GPSFixMoving> cloneOfFindelsTrack = cloneBySerialization(findelsTrack);
assertEquals(Util.size(findelsTrack.getFixes()), Util.size(cloneOfFindelsTrack.getFixes()));
Pair<Integer, Long> sizeAndTime = getSerializationSizeAndTime(findelsTrack);
System.out.println(sizeAndTime);
assertTrue(sizeAndTime.getA() > 100000);
}
}
@@ -15,6 +15,7 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
public class TracTracTrackedLegImpl implements TrackedLeg { public class TracTracTrackedLegImpl implements TrackedLeg {
private static final long serialVersionUID = 2396033396354531099L;
private final Leg leg; private final Leg leg;
private final Map<Competitor, TrackedLegOfCompetitor> trackedLegsOfCompetitors; private final Map<Competitor, TrackedLegOfCompetitor> trackedLegsOfCompetitors;
private final TrackedRace trackedRace; private final TrackedRace trackedRace;
@@ -24,6 +24,7 @@ import com.tractrac.ResultAPI.LiveResultItem;
import com.tractrac.ResultAPI.MarkResultItem; import com.tractrac.ResultAPI.MarkResultItem;
public class TracTracTrackedLegOfCompetitor implements TrackedLegOfCompetitor { public class TracTracTrackedLegOfCompetitor implements TrackedLegOfCompetitor {
private static final long serialVersionUID = 2515934387641015173L;
private final TracTracTrackedRaceImpl trackedRace; private final TracTracTrackedRaceImpl trackedRace;
private final Leg leg; private final Leg leg;
private final Competitor competitor; private final Competitor competitor;
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.base; package com.sap.sailing.domain.base;
public interface Leg { import java.io.Serializable;
public interface Leg extends Serializable {
Waypoint getFrom(); Waypoint getFrom();
Waypoint getTo(); Waypoint getTo();
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
public abstract class AbstractSpeedWithBearingImpl extends AbstractSpeedImpl implements SpeedWithBearing { public abstract class AbstractSpeedWithBearingImpl extends AbstractSpeedImpl implements SpeedWithBearing {
private static final long serialVersionUID = -8594305027333573010L;
private final Bearing bearing; private final Bearing bearing;
protected AbstractSpeedWithBearingImpl(Bearing bearing) { protected AbstractSpeedWithBearingImpl(Bearing bearing) {
@@ -5,13 +5,16 @@ import java.util.Comparator;
import java.util.Date; import java.util.Date;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.util.SerializableComparator;
public abstract class AbstractTimePoint implements TimePoint { public abstract class AbstractTimePoint implements TimePoint {
private static final long serialVersionUID = 8825508619301420378L; private static final long serialVersionUID = 8825508619301420378L;
private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
public static Comparator<TimePoint> TIMEPOINT_COMPARATOR = new Comparator<TimePoint>() { public static Comparator<TimePoint> TIMEPOINT_COMPARATOR = new SerializableComparator<TimePoint>() {
private static final long serialVersionUID = 7644726881387366025L;
@Override @Override
public int compare(TimePoint o1, TimePoint o2) { public int compare(TimePoint o1, TimePoint o2) {
long milliDiff = o1.asMillis() - o2.asMillis(); long milliDiff = o1.asMillis() - o2.asMillis();
@@ -9,6 +9,8 @@ import com.sap.sailing.domain.confidence.ScalableValue;
public class BearingWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<Pair<Double, Double>, Bearing, RelativeTo> public class BearingWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<Pair<Double, Double>, Bearing, RelativeTo>
implements BearingWithConfidence<RelativeTo>, IsScalable<Pair<Double, Double>, Bearing> { implements BearingWithConfidence<RelativeTo>, IsScalable<Pair<Double, Double>, Bearing> {
private static final long serialVersionUID = 1624026377840747818L;
public BearingWithConfidenceImpl(Bearing bearing, double confidence, RelativeTo relativeTo) { public BearingWithConfidenceImpl(Bearing bearing, double confidence, RelativeTo relativeTo) {
super(bearing, confidence, relativeTo); super(bearing, confidence, relativeTo);
} }
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.base.impl; package com.sap.sailing.domain.base.impl;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -62,6 +64,13 @@ public class CourseImpl extends NamedImpl implements Course {
} }
} }
/**
* Synchronize on this object to avoid concurrent modifications of the underlying waypoints list
*/
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
/** /**
* For access by {@link LegImpl} * For access by {@link LegImpl}
*/ */
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.base.impl;
import com.sap.sailing.domain.confidence.HasConfidence; import com.sap.sailing.domain.confidence.HasConfidence;
public class HasConfidenceImpl<ValueType, BaseType, RelativeTo> implements HasConfidence<ValueType, BaseType, RelativeTo> { public class HasConfidenceImpl<ValueType, BaseType, RelativeTo> implements HasConfidence<ValueType, BaseType, RelativeTo> {
private static final long serialVersionUID = -1635823148449693024L;
private final double confidence; private final double confidence;
private final RelativeTo relativeTo; private final RelativeTo relativeTo;
private final BaseType object; private final BaseType object;
@@ -8,6 +8,7 @@ import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl; import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl;
public class KilometersPerHourSpeedWithBearingImpl extends KilometersPerHourSpeedImpl implements SpeedWithBearing { public class KilometersPerHourSpeedWithBearingImpl extends KilometersPerHourSpeedImpl implements SpeedWithBearing {
private static final long serialVersionUID = 5749611820871048625L;
private final Bearing bearing; private final Bearing bearing;
public KilometersPerHourSpeedWithBearingImpl(double speedInKilometersPerHour, Bearing bearing) { public KilometersPerHourSpeedWithBearingImpl(double speedInKilometersPerHour, Bearing bearing) {
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.common.AbstractSpeedImpl;
import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.Speed;
public class KnotSpeedImpl extends AbstractSpeedImpl implements Speed { public class KnotSpeedImpl extends AbstractSpeedImpl implements Speed {
private static final long serialVersionUID = 5150851454271610069L;
private final double knots; private final double knots;
public KnotSpeedImpl(double knots) { public KnotSpeedImpl(double knots) {
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.base.impl;
import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Bearing;
public class KnotSpeedWithBearingImpl extends AbstractSpeedWithBearingImpl { public class KnotSpeedWithBearingImpl extends AbstractSpeedWithBearingImpl {
private static final long serialVersionUID = -2300633070560631053L;
private final double speedInKnots; private final double speedInKnots;
public KnotSpeedWithBearingImpl(double speedInKnots, Bearing bearing) { public KnotSpeedWithBearingImpl(double speedInKnots, Bearing bearing) {
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.Waypoint;
public class LegImpl implements Leg { public class LegImpl implements Leg {
private static final long serialVersionUID = -6730954156357241076L;
private final CourseImpl course; private final CourseImpl course;
private final int indexOfStartWaypoint; private final int indexOfStartWaypoint;
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.common.AbstractDistance;
import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.Distance;
public class MeterDistance extends AbstractDistance { public class MeterDistance extends AbstractDistance {
private static final long serialVersionUID = 1205385257141317881L;
private final double meters; private final double meters;
public MeterDistance(double meters) { public MeterDistance(double meters) {
@@ -6,6 +6,8 @@ import com.sap.sailing.domain.confidence.IsScalable;
public class PositionWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<ScalablePosition, Position, RelativeTo> implements public class PositionWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<ScalablePosition, Position, RelativeTo> implements
PositionWithConfidence<RelativeTo>, IsScalable<ScalablePosition, Position> { PositionWithConfidence<RelativeTo>, IsScalable<ScalablePosition, Position> {
private static final long serialVersionUID = -3857039006152257909L;
public PositionWithConfidenceImpl(Position position, double confidence, RelativeTo relativeTo) { public PositionWithConfidenceImpl(Position position, double confidence, RelativeTo relativeTo) {
super(position, confidence, relativeTo); super(position, confidence, relativeTo);
} }
@@ -10,6 +10,8 @@ import com.sap.sailing.domain.confidence.ScalableValue;
public class SpeedWithBearingWithConfidenceImpl<RelativeTo> extends public class SpeedWithBearingWithConfidenceImpl<RelativeTo> extends
HasConfidenceImpl<Triple<Speed, Double, Double>, SpeedWithBearing, RelativeTo> implements HasConfidenceImpl<Triple<Speed, Double, Double>, SpeedWithBearing, RelativeTo> implements
SpeedWithBearingWithConfidence<RelativeTo>, IsScalable<Triple<Speed, Double, Double>, SpeedWithBearing> { SpeedWithBearingWithConfidence<RelativeTo>, IsScalable<Triple<Speed, Double, Double>, SpeedWithBearing> {
private static final long serialVersionUID = -4811576094614673625L;
public SpeedWithBearingWithConfidenceImpl(SpeedWithBearing speedWithBearing, double confidence, RelativeTo relativeTo) { public SpeedWithBearingWithConfidenceImpl(SpeedWithBearing speedWithBearing, double confidence, RelativeTo relativeTo) {
super(speedWithBearing, confidence, relativeTo); super(speedWithBearing, confidence, relativeTo);
} }
@@ -5,6 +5,8 @@ import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.confidence.ScalableValue; import com.sap.sailing.domain.confidence.ScalableValue;
public class SpeedWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<Double, Speed, RelativeTo> implements SpeedWithConfidence<RelativeTo> { public class SpeedWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<Double, Speed, RelativeTo> implements SpeedWithConfidence<RelativeTo> {
private static final long serialVersionUID = -3122580369653833748L;
public SpeedWithConfidenceImpl(Speed object, double confidence, RelativeTo relativeTo) { public SpeedWithConfidenceImpl(Speed object, double confidence, RelativeTo relativeTo) {
super(object, confidence, relativeTo); super(object, confidence, relativeTo);
} }
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.confidence; package com.sap.sailing.domain.confidence;
import java.io.Serializable;
import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.GPSFixTrack;
@@ -42,7 +44,7 @@ import com.sap.sailing.domain.tracking.GPSFixTrack;
* a correspondingly-typed weigher, such a value with confidence can be aggregated with * a correspondingly-typed weigher, such a value with confidence can be aggregated with
* other values, again relative to (maybe a different) time point. * other values, again relative to (maybe a different) time point.
*/ */
public interface HasConfidence<ValueType, BaseType, RelativeTo> { public interface HasConfidence<ValueType, BaseType, RelativeTo> extends Serializable {
/** /**
* A confidence is a number between 0.0 and 1.0 (inclusive) where 0.0 means that the value is randomly guessed while * A confidence is a number between 0.0 and 1.0 (inclusive) where 0.0 means that the value is randomly guessed while
* 1.0 means the value is authoritatively known for a fact. It represents the weight with which a value is to be * 1.0 means the value is authoritatively known for a fact. It represents the weight with which a value is to be
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.confidence; package com.sap.sailing.domain.confidence;
public interface IsScalable<ValueType, BaseType> { import java.io.Serializable;
public interface IsScalable<ValueType, BaseType> extends Serializable {
ScalableValue<ValueType, BaseType> getScalableValue(); ScalableValue<ValueType, BaseType> getScalableValue();
} }
@@ -1,11 +1,13 @@
package com.sap.sailing.domain.confidence; package com.sap.sailing.domain.confidence;
import java.io.Serializable;
/** /**
* A weigher can compute a confidence value for a distance of two <code>RelativeTo</code> objects. * A weigher can compute a confidence value for a distance of two <code>RelativeTo</code> objects.
* *
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
*/ */
public interface Weigher<RelativeTo> { public interface Weigher<RelativeTo> extends Serializable {
/** /**
* Computes a confidence, based on some weighed notion of "distance" between the two <code>RelativeTo</code> objects. * Computes a confidence, based on some weighed notion of "distance" between the two <code>RelativeTo</code> objects.
* *
@@ -10,6 +10,8 @@ public class ConfidenceBasedAveragerFactoryImpl implements ConfidenceFactory {
@Override @Override
public <RelativeTo> Weigher<RelativeTo> createConstantWeigher(final double constantConfidence) { public <RelativeTo> Weigher<RelativeTo> createConstantWeigher(final double constantConfidence) {
return new Weigher<RelativeTo>() { return new Weigher<RelativeTo>() {
private static final long serialVersionUID = 8693131975511149792L;
@Override @Override
public double getConfidence(RelativeTo fix, RelativeTo request) { public double getConfidence(RelativeTo fix, RelativeTo request) {
return constantConfidence; return constantConfidence;
@@ -11,6 +11,8 @@ import com.sap.sailing.domain.confidence.Weigher;
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
*/ */
public class ExponentialTimeDifferenceWeigher implements Weigher<TimePoint> { public class ExponentialTimeDifferenceWeigher implements Weigher<TimePoint> {
private static final long serialVersionUID = 1832731495731693670L;
private final static double logHalf = Math.log(0.5); private final static double logHalf = Math.log(0.5);
private final long halfConfidenceAfterMilliseconds; private final long halfConfidenceAfterMilliseconds;
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.confidence.Weigher; import com.sap.sailing.domain.confidence.Weigher;
public class HyperbolicTimeDifferenceWeigher implements Weigher<TimePoint> { public class HyperbolicTimeDifferenceWeigher implements Weigher<TimePoint> {
private static final long serialVersionUID = 4378168079868145134L;
private final long halfConfidenceAfterMilliseconds; private final long halfConfidenceAfterMilliseconds;
public HyperbolicTimeDifferenceWeigher(long halfConfidenceAfterMilliseconds) { public HyperbolicTimeDifferenceWeigher(long halfConfidenceAfterMilliseconds) {
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.confidence.Weigher;
* *
*/ */
public class PositionAndTimePointWeigher implements Weigher<Pair<Position, TimePoint>> { public class PositionAndTimePointWeigher implements Weigher<Pair<Position, TimePoint>> {
private static final long serialVersionUID = -262428237738496818L;
private final Weigher<TimePoint> weigher; private final Weigher<TimePoint> weigher;
public PositionAndTimePointWeigher(long halfConfidenceAfterMilliseconds) { public PositionAndTimePointWeigher(long halfConfidenceAfterMilliseconds) {
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.confidence.impl;
import com.sap.sailing.domain.confidence.HasConfidenceAndIsScalable; import com.sap.sailing.domain.confidence.HasConfidenceAndIsScalable;
public class ScalableDoubleWithConfidence<RelativeTo> extends ScalableDouble implements HasConfidenceAndIsScalable<Double, Double, RelativeTo> { public class ScalableDoubleWithConfidence<RelativeTo> extends ScalableDouble implements HasConfidenceAndIsScalable<Double, Double, RelativeTo> {
private static final long serialVersionUID = 1042652394404557792L;
private final double confidence; private final double confidence;
private final RelativeTo relativeTo; private final RelativeTo relativeTo;
@@ -3,11 +3,11 @@ package com.sap.sailing.domain.leaderboard;
import java.util.Map; import java.util.Map;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.Named; import com.sap.sailing.domain.common.Named;
import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.MaxPointsReason;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
/** /**
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.leaderboard; package com.sap.sailing.domain.leaderboard;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
@@ -15,34 +16,6 @@ import com.sap.sailing.domain.tracking.TrackedRace;
* *
*/ */
public interface ScoreCorrection { public interface ScoreCorrection {
/**
* The reasons why a competitor may get the maximum number of points, usually equaling the
* number of competitors enlisted for the regatta plus one.
*
* @author Axel Uhl (d043530)
*
*/
enum MaxPointsReason {
/** The competitor finished the race properly */
NONE,
/** Did Not Start */
DNS,
/** Did Not Finish */
DNF,
/** DiSQualified */
DSQ,
/** On Course Side (jumped the gun) */
OCS,
/** Disqualified, non-discardable */
DND,
/** Black Flag Disqualified */
BFD,
/** Did Not Compete */
DNC,
/** Retired After Finishing */
RAF
};
public interface Result { public interface Result {
int getCorrectedScore(); int getCorrectedScore();
MaxPointsReason getMaxPointsReason(); MaxPointsReason getMaxPointsReason();
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.leaderboard; package com.sap.sailing.domain.leaderboard;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.MaxPointsReason;
public interface SettableScoreCorrection extends ScoreCorrection { public interface SettableScoreCorrection extends ScoreCorrection {
@@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.Named; import com.sap.sailing.domain.common.Named;
import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
@@ -16,7 +17,6 @@ import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.Result; import com.sap.sailing.domain.leaderboard.ScoreCorrection.Result;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection; import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule; import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
@@ -4,11 +4,11 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection; import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
@@ -33,7 +33,7 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
private final Map<Pair<Competitor, RaceInLeaderboard>, Integer> correctedScores; private final Map<Pair<Competitor, RaceInLeaderboard>, Integer> correctedScores;
public ScoreCorrectionImpl() { public ScoreCorrectionImpl() {
this.maxPointsReasons = new HashMap<Util.Pair<Competitor,RaceInLeaderboard>, ScoreCorrection.MaxPointsReason>(); this.maxPointsReasons = new HashMap<Util.Pair<Competitor,RaceInLeaderboard>, MaxPointsReason>();
this.correctedScores = new HashMap<Util.Pair<Competitor,RaceInLeaderboard>, Integer>(); this.correctedScores = new HashMap<Util.Pair<Competitor,RaceInLeaderboard>, Integer>();
} }
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.tracking; package com.sap.sailing.domain.tracking;
public interface GPSTrackListener<ItemType> { import java.io.Serializable;
public interface GPSTrackListener<ItemType> extends Serializable {
void gpsFixReceived(GPSFix fix, ItemType item); void gpsFixReceived(GPSFix fix, ItemType item);
void speedAveragingChanged(long oldMillisecondsOverWhichToAverage, long newMillisecondsOverWhichToAverage); void speedAveragingChanged(long oldMillisecondsOverWhichToAverage, long newMillisecondsOverWhichToAverage);
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.tracking; package com.sap.sailing.domain.tracking;
import java.io.Serializable;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
@@ -9,7 +10,7 @@ import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
public interface TrackedLeg { public interface TrackedLeg extends Serializable {
Leg getLeg(); Leg getLeg();
Iterable<TrackedLegOfCompetitor> getTrackedLegsOfCompetitors(); Iterable<TrackedLegOfCompetitor> getTrackedLegsOfCompetitors();
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.tracking; package com.sap.sailing.domain.tracking;
import java.io.Serializable;
import java.util.List; import java.util.List;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
@@ -11,7 +12,7 @@ import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.TimePoint;
public interface TrackedLegOfCompetitor { public interface TrackedLegOfCompetitor extends Serializable {
Leg getLeg(); Leg getLeg();
Competitor getCompetitor(); Competitor getCompetitor();
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.tracking; package com.sap.sailing.domain.tracking;
import java.io.Serializable;
import java.util.Map; import java.util.Map;
import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSource;
@@ -13,7 +14,7 @@ import com.sap.sailing.domain.common.WindSource;
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
* *
*/ */
public interface WindStore { public interface WindStore extends Serializable {
WindTrack getWindTrack(TrackedEvent trackedEvent, TrackedRace trackedRace, WindSource windSource, WindTrack getWindTrack(TrackedEvent trackedEvent, TrackedRace trackedRace, WindSource windSource,
long millisecondsOverWhichToAverage, long delayForWindEstimationCacheInvalidation); long millisecondsOverWhichToAverage, long delayForWindEstimationCacheInvalidation);
@@ -17,6 +17,8 @@ import com.sap.sailing.domain.tracking.WindTrack;
*/ */
public class CombinedWindAsNavigableSet extends VirtualWindFixesAsNavigableSet { public class CombinedWindAsNavigableSet extends VirtualWindFixesAsNavigableSet {
private static final long serialVersionUID = -153959652212518644L;
public CombinedWindAsNavigableSet(WindTrack track, TrackedRace trackedRace, long resolutionInMilliseconds) { public CombinedWindAsNavigableSet(WindTrack track, TrackedRace trackedRace, long resolutionInMilliseconds) {
super(track, trackedRace, resolutionInMilliseconds); super(track, trackedRace, resolutionInMilliseconds);
} }
@@ -25,6 +25,8 @@ public class CompactGPSFixMovingImpl extends CompactGPSFixImpl implements GPSFix
private final double degBearing; private final double degBearing;
private class CompactSpeedWithBearing extends AbstractSpeedImpl implements SpeedWithBearing { private class CompactSpeedWithBearing extends AbstractSpeedImpl implements SpeedWithBearing {
private static final long serialVersionUID = 1802065090733146728L;
@Override @Override
public double getKnots() { public double getKnots() {
return knotSpeed; return knotSpeed;
@@ -67,6 +69,8 @@ public class CompactGPSFixMovingImpl extends CompactGPSFixImpl implements GPSFix
} }
private class CompactBearing extends AbstractBearing { private class CompactBearing extends AbstractBearing {
private static final long serialVersionUID = -6474909210513108635L;
@Override @Override
public double getDegrees() { public double getDegrees() {
return degBearing; return degBearing;
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.tracking.impl; package com.sap.sailing.domain.tracking.impl;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Collection; import java.util.Collection;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.HashMap; import java.util.HashMap;
@@ -60,6 +62,14 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
getOrCreateWindTrack(windSource).addListener(this); getOrCreateWindTrack(windSource).addListener(this);
} }
} }
/**
* Synchronized object serialization on this object so that incoming new data doesn't disrupt the serialization process.
*/
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
/** /**
* {@link #raceIsKnownToStartUpwind} (see also {@link #raceIsKnownToStartUpwind()}) is initialized based on the <code>race</code>'s * {@link #raceIsKnownToStartUpwind} (see also {@link #raceIsKnownToStartUpwind()}) is initialized based on the <code>race</code>'s
* {@link RaceDefinition#getBoatClass()} boat class's {@link BoatClass#typicallyStartsUpwind()} result. It can be changed * {@link RaceDefinition#getBoatClass()} boat class's {@link BoatClass#typicallyStartsUpwind()} result. It can be changed
@@ -116,6 +126,8 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
protected DynamicGPSFixTrackImpl<Buoy> createBuoyTrack(Buoy buoy) { protected DynamicGPSFixTrackImpl<Buoy> createBuoyTrack(Buoy buoy) {
DynamicGPSFixTrackImpl<Buoy> result = super.createBuoyTrack(buoy); DynamicGPSFixTrackImpl<Buoy> result = super.createBuoyTrack(buoy);
result.addListener(new GPSTrackListener<Buoy>() { result.addListener(new GPSTrackListener<Buoy>() {
private static final long serialVersionUID = -2855787105725103732L;
@Override @Override
public void gpsFixReceived(GPSFix fix, Buoy buoy) { public void gpsFixReceived(GPSFix fix, Buoy buoy) {
notifyListeners(fix, buoy); notifyListeners(fix, buoy);
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindTrack;
public class EmptyWindStore implements WindStore { public class EmptyWindStore implements WindStore {
private static final long serialVersionUID = -981813704281564319L;
public static EmptyWindStore INSTANCE = new EmptyWindStore(); public static EmptyWindStore INSTANCE = new EmptyWindStore();
@Override @Override
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.tracking.impl; package com.sap.sailing.domain.tracking.impl;
import java.io.Serializable;
import java.util.Comparator; import java.util.Comparator;
import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.MarkPassing;
@@ -13,7 +14,8 @@ import com.sap.sailing.domain.tracking.MarkPassing;
* @author Axel Uhl (D043530) * @author Axel Uhl (D043530)
* *
*/ */
public class MarkPassingByTimeComparator implements Comparator<MarkPassing> { public class MarkPassingByTimeComparator implements Comparator<MarkPassing>, Serializable {
private static final long serialVersionUID = 5758820139503482888L;
public static MarkPassingByTimeComparator INSTANCE = new MarkPassingByTimeComparator(); public static MarkPassingByTimeComparator INSTANCE = new MarkPassingByTimeComparator();
@Override @Override
@@ -1,10 +1,12 @@
package com.sap.sailing.domain.tracking.impl; package com.sap.sailing.domain.tracking.impl;
import java.io.Serializable;
import java.util.Comparator; import java.util.Comparator;
import com.sap.sailing.domain.base.Timed; import com.sap.sailing.domain.base.Timed;
public class TimedComparator implements Comparator<Timed> { public class TimedComparator implements Comparator<Timed>, Serializable {
private static final long serialVersionUID = 1604511471599854988L;
public static final Comparator<Timed> INSTANCE = new TimedComparator(); public static final Comparator<Timed> INSTANCE = new TimedComparator();
@Override @Override
@@ -1,7 +1,10 @@
package com.sap.sailing.domain.tracking.impl; package com.sap.sailing.domain.tracking.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.NavigableSet; import java.util.NavigableSet;
@@ -28,6 +31,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind; import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.util.SerializableComparator;
import com.sap.sailing.util.impl.ArrayListNavigableSet; import com.sap.sailing.util.impl.ArrayListNavigableSet;
/** /**
@@ -86,9 +90,10 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
*/ */
private final long delayForCacheInvalidationInMilliseconds; private final long delayForCacheInvalidationInMilliseconds;
private final Timer cacheInvalidationTimer; private transient Timer cacheInvalidationTimer;
private static class InvalidationInterval { private static class InvalidationInterval implements Serializable {
private static final long serialVersionUID = -6406690520919193690L;
private WindWithConfidence<TimePoint> start; private WindWithConfidence<TimePoint> start;
private TimePoint end; private TimePoint end;
public InvalidationInterval() { public InvalidationInterval() {
@@ -143,7 +148,9 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
this.cacheInvalidationTimer = new Timer("TrackBasedEstimationWindTrackImpl cache invalidation timer for race "+getTrackedRace().getRace()); this.cacheInvalidationTimer = new Timer("TrackBasedEstimationWindTrackImpl cache invalidation timer for race "+getTrackedRace().getRace());
this.scheduledInvalidationInterval = new InvalidationInterval(); this.scheduledInvalidationInterval = new InvalidationInterval();
cache = new ArrayListNavigableSet<WindWithConfidence<TimePoint>>( cache = new ArrayListNavigableSet<WindWithConfidence<TimePoint>>(
new Comparator<WindWithConfidence<TimePoint>>() { new SerializableComparator<WindWithConfidence<TimePoint>>() {
private static final long serialVersionUID = 5760349397418542705L;
@Override @Override
public int compare(WindWithConfidence<TimePoint> o1, WindWithConfidence<TimePoint> o2) { public int compare(WindWithConfidence<TimePoint> o1, WindWithConfidence<TimePoint> o2) {
return o1.getObject().getTimePoint().compareTo(o2.getObject().getTimePoint()); return o1.getObject().getTimePoint().compareTo(o2.getObject().getTimePoint());
@@ -158,6 +165,18 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
this.timePointsWithCachedNullResultFastContains = new HashSet<TimePoint>(); this.timePointsWithCachedNullResultFastContains = new HashSet<TimePoint>();
} }
/**
* Synchronizes serialization on this object to avoid the cache being updated while being written.
*/
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
private void readObject(final ObjectInputStream s) throws ClassNotFoundException, IOException {
s.defaultReadObject();
cacheInvalidationTimer = new Timer("TrackBasedEstimationWindTrackImpl cache invalidation timer for race "+getTrackedRace().getRace());
}
/** /**
* Constructs this track with cache invalidation happening after half the * Constructs this track with cache invalidation happening after half the
* {@link TrackedRace#getMillisecondsOverWhichToAverageWind() wind averaging interval specified by the tracked race} * {@link TrackedRace#getMillisecondsOverWhichToAverageWind() wind averaging interval specified by the tracked race}
@@ -234,7 +253,6 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
*/ */
private synchronized void invalidateCache() { private synchronized void invalidateCache() {
synchronized (scheduledInvalidationInterval) { synchronized (scheduledInvalidationInterval) {
// FIXME see bug 452: synchronize also on the cached fixes
Iterator<WindWithConfidence<TimePoint>> iter = (scheduledInvalidationInterval.getStart() == null ? getCachedFixes() Iterator<WindWithConfidence<TimePoint>> iter = (scheduledInvalidationInterval.getStart() == null ? getCachedFixes()
: getCachedFixes().tailSet(scheduledInvalidationInterval.getStart(), /* inclusive */true)).iterator(); : getCachedFixes().tailSet(scheduledInvalidationInterval.getStart(), /* inclusive */true)).iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
@@ -429,6 +447,8 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
* *
*/ */
public class EstimatedWindFixesAsNavigableSet extends VirtualWindFixesAsNavigableSet { public class EstimatedWindFixesAsNavigableSet extends VirtualWindFixesAsNavigableSet {
private static final long serialVersionUID = -6902341522276949873L;
public EstimatedWindFixesAsNavigableSet(TrackedRace trackedRace) { public EstimatedWindFixesAsNavigableSet(TrackedRace trackedRace) {
this(trackedRace, null, null); this(trackedRace, null, null);
} }
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.tracking.impl; package com.sap.sailing.domain.tracking.impl;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NavigableSet; import java.util.NavigableSet;
@@ -42,6 +44,13 @@ public abstract class TrackImpl<FixType extends Timed> implements Track<FixType>
this.fixes = fixes; this.fixes = fixes;
} }
/**
* Synchronize the serialization such that no fixes are added while serializing
*/
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
/** /**
* Callers that want to iterate over the collection returned need to synchronize on <code>this</code> object to avoid * Callers that want to iterate over the collection returned need to synchronize on <code>this</code> object to avoid
* {@link ConcurrentModificationException}s. * {@link ConcurrentModificationException}s.
@@ -28,6 +28,8 @@ import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind; import com.sap.sailing.domain.tracking.Wind;
public class TrackedLegImpl implements TrackedLeg, RaceChangeListener { public class TrackedLegImpl implements TrackedLeg, RaceChangeListener {
private static final long serialVersionUID = -1944668527284130545L;
private final static Logger logger = Logger.getLogger(TrackedLegImpl.class.getName()); private final static Logger logger = Logger.getLogger(TrackedLegImpl.class.getName());
private final static double UPWIND_DOWNWIND_TOLERANCE_IN_DEG = 60; // TracTrac does 22.5, Marcus Baur suggest 40; Nils Schröder suggests 60 private final static double UPWIND_DOWNWIND_TOLERANCE_IN_DEG = 60; // TracTrac does 22.5, Marcus Baur suggest 40; Nils Schröder suggests 60
@@ -31,6 +31,7 @@ import com.sap.sailing.domain.tracking.Wind;
* *
*/ */
public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor { public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
private static final long serialVersionUID = -7060076837717432808L;
private final TrackedLegImpl trackedLeg; private final TrackedLegImpl trackedLeg;
private final Competitor competitor; private final Competitor competitor;
@@ -82,8 +82,6 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
// TODO make this variable // TODO make this variable
private static final long DELAY_FOR_CACHE_CLEARING_IN_MILLISECONDS = 7500; private static final long DELAY_FOR_CACHE_CLEARING_IN_MILLISECONDS = 7500;
// TODO observe the race course; if it changes, update leg structures; consider fine-grained update events that tell
// what changed
private final RaceDefinition race; private final RaceDefinition race;
private final TrackedEvent trackedEvent; private final TrackedEvent trackedEvent;
@@ -150,6 +148,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
private final LinkedHashMap<Leg, TrackedLeg> trackedLegs; private final LinkedHashMap<Leg, TrackedLeg> trackedLegs;
private final Map<Competitor, GPSFixTrack<Competitor, GPSFixMoving>> tracks; private final Map<Competitor, GPSFixTrack<Competitor, GPSFixMoving>> tracks;
private final Map<Competitor, NavigableSet<MarkPassing>> markPassingsForCompetitor; private final Map<Competitor, NavigableSet<MarkPassing>> markPassingsForCompetitor;
/** /**
@@ -183,7 +182,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
private final WindStore windStore; private final WindStore windStore;
private Timer cacheInvalidationTimer; private transient Timer cacheInvalidationTimer;
public TrackedRaceImpl(TrackedEvent trackedEvent, RaceDefinition race, WindStore windStore, public TrackedRaceImpl(TrackedEvent trackedEvent, RaceDefinition race, WindStore windStore,
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed) { long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed) {
@@ -1502,6 +1501,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
} }
private class StartToNextMarkCacheInvalidationListener implements GPSTrackListener<Buoy> { private class StartToNextMarkCacheInvalidationListener implements GPSTrackListener<Buoy> {
private static final long serialVersionUID = 3540278554797445085L;
private final GPSFixTrack<Buoy, GPSFix> listeningTo; private final GPSFixTrack<Buoy, GPSFix> listeningTo;
public StartToNextMarkCacheInvalidationListener(GPSFixTrack<Buoy, GPSFix> listeningTo) { public StartToNextMarkCacheInvalidationListener(GPSFixTrack<Buoy, GPSFix> listeningTo) {
@@ -28,6 +28,8 @@ import com.sap.sailing.util.impl.DescendingNavigableSet;
* *
*/ */
public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiableNavigableSet<Wind> { public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiableNavigableSet<Wind> {
private static final long serialVersionUID = -7191543758261688727L;
/** /**
* The time resolution is one second. * The time resolution is one second.
*/ */
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.tracking.impl; package com.sap.sailing.domain.tracking.impl;
import java.io.Serializable;
import java.util.Comparator; import java.util.Comparator;
import com.sap.sailing.domain.base.Timed; import com.sap.sailing.domain.base.Timed;
@@ -13,7 +14,8 @@ import com.sap.sailing.domain.tracking.Wind;
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
* *
*/ */
public class WindComparator implements Comparator<Timed> { public class WindComparator implements Comparator<Timed>, Serializable {
private static final long serialVersionUID = -7202702713168912931L;
public static final Comparator<Timed> INSTANCE = new WindComparator(); public static final Comparator<Timed> INSTANCE = new WindComparator();
@Override @Override
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.WindWithConfidence; import com.sap.sailing.domain.tracking.WindWithConfidence;
public class WindWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<ScalableWind, Wind, RelativeTo> implements WindWithConfidence<RelativeTo> { public class WindWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<ScalableWind, Wind, RelativeTo> implements WindWithConfidence<RelativeTo> {
private static final long serialVersionUID = -644015582690775666L;
private final boolean useSpeed; private final boolean useSpeed;
public WindWithConfidenceImpl(Wind object, double confidence, RelativeTo relativeTo, boolean useSpeed) { public WindWithConfidenceImpl(Wind object, double confidence, RelativeTo relativeTo, boolean useSpeed) {
@@ -0,0 +1,19 @@
package com.sap.sailing.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.io.StreamCorruptedException;
public class ObjectInputStreamWithConfigurableClassLoader extends ObjectInputStream {
public ObjectInputStreamWithConfigurableClassLoader(InputStream in) throws IOException, StreamCorruptedException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
String className = classDesc.getName();
return Thread.currentThread().getContextClassLoader().loadClass(className);
}
}
@@ -0,0 +1,7 @@
package com.sap.sailing.util;
import java.io.Serializable;
import java.util.Comparator;
public interface SerializableComparator<T> extends Comparator<T>, Serializable {
}
@@ -1,9 +1,12 @@
package com.sap.sailing.util.impl; package com.sap.sailing.util.impl;
import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.NavigableSet; import java.util.NavigableSet;
public abstract class AbstractUnmodifiableNavigableSet<E> implements NavigableSet<E> { public abstract class AbstractUnmodifiableNavigableSet<E> implements NavigableSet<E>, Serializable {
private static final long serialVersionUID = -256926414640453225L;
@Override @Override
public boolean add(E e) { public boolean add(E e) {
@@ -1,5 +1,6 @@
package com.sap.sailing.util.impl; package com.sap.sailing.util.impl;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -34,7 +35,8 @@ import java.util.SortedSet;
* *
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
*/ */
public class ArrayListNavigableSet<E> implements NavigableSet<E> { public class ArrayListNavigableSet<E> implements NavigableSet<E>, Serializable {
private static final long serialVersionUID = 6923963699509907975L;
private final List<E> list; private final List<E> list;
private final Comparator<? super E> comparator; private final Comparator<? super E> comparator;
@@ -13,6 +13,7 @@ import java.util.SortedSet;
* @author Axel Uhl (D043530) * @author Axel Uhl (D043530)
*/ */
public class UnmodifiableNavigableSet<E> extends AbstractUnmodifiableNavigableSet<E> implements NavigableSet<E> { public class UnmodifiableNavigableSet<E> extends AbstractUnmodifiableNavigableSet<E> implements NavigableSet<E> {
private static final long serialVersionUID = -2829360843200741699L;
private final NavigableSet<E> set; private final NavigableSet<E> set;
public UnmodifiableNavigableSet(NavigableSet<E> delegate) { public UnmodifiableNavigableSet(NavigableSet<E> delegate) {
@@ -1,4 +1,5 @@
#Fri Apr 20 10:37:19 CEST 2012
eclipse.preferences.version=1 eclipse.preferences.version=1
entryPointModules= entryPointModules=
filesCopiedToWebInfLib=gwt-servlet.jar filesCopiedToWebInfLib=gwt-servlet.jar
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+UFJFVFRZPC9vdXRwdXQtc3R5bGU+PGV4dHJhLWFyZ3M+PCFbQ0RBVEFbLXdhciAuIC1sb2NhbFdvcmtlcnMgMyAtc3RyaWN0IC1sb2dMZXZlbCBUUkFDRV1dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14MTAyNG1dXT48L3ZtLWFyZ3M+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLkFkbWluQ29uc29sZTwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5MZWFkZXJib2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5MZWFkZXJib2FyZEVkaXRpbmc8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuUmFjZUJvYXJkPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlNpbXVsYXRvcjwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48L2d3dC1jb21waWxlLXNldHRpbmdzPg\=\= gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+UFJFVFRZPC9vdXRwdXQtc3R5bGU+PGV4dHJhLWFyZ3M+PCFbQ0RBVEFbLXdhciAuIC1sb2NhbFdvcmtlcnMgMyAtc3RyaWN0IC1sb2dMZXZlbCBUUkFDRV1dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14MTAyNG1dXT48L3ZtLWFyZ3M+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlNpbXVsYXRvcjwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48L2d3dC1jb21waWxlLXNldHRpbmdzPg\=\=
@@ -26,12 +26,13 @@ Export-Package: com.sap.sailing.gwt.ui.client;x-friends:="com.sap.sailing.gwt.ui
com.sap.sailing.gwt.ui.leaderboardedit;x-friends:="com.sap.sailing.gwt.ui.test", com.sap.sailing.gwt.ui.leaderboardedit;x-friends:="com.sap.sailing.gwt.ui.test",
com.sap.sailing.gwt.ui.server;x-friends:="com.sap.sailing.gwt.ui.test", com.sap.sailing.gwt.ui.server;x-friends:="com.sap.sailing.gwt.ui.test",
com.sap.sailing.gwt.ui.shared;x-friends:="com.sap.sailing.gwt.ui.test" com.sap.sailing.gwt.ui.shared;x-friends:="com.sap.sailing.gwt.ui.test"
Import-Package: org.osgi.framework, Import-Package: com.sap.sailing.gwt.ui.shared,
org.osgi.util.tracker,
javax.servlet;version="2.5.0", javax.servlet;version="2.5.0",
javax.servlet.http;version="2.5.0", javax.servlet.http;version="2.5.0",
org.json.simple, org.json.simple,
org.json.simple.parser org.json.simple.parser,
org.osgi.framework,
org.osgi.util.tracker
Web-ContextPath: /gwt Web-ContextPath: /gwt
Bundle-ClassPath: WEB-INF/classes/, Bundle-ClassPath: WEB-INF/classes/,
WEB-INF/lib/gwt-maps.jar, WEB-INF/lib/gwt-maps.jar,
@@ -4,7 +4,7 @@
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/> <stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> <booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES"> <listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/> <listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
</listAttribute> </listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/AdminConsole.html"/> <stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/AdminConsole.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
@@ -19,7 +19,7 @@
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/UserManagement.html com.sap.sailing.gwt.ui.UserManagement -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard"/> <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/UserManagement.html com.sap.sailing.gwt.ui.UserManagement -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx1024m"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx1024m"/>
</launchConfiguration> </launchConfiguration>
@@ -573,7 +573,12 @@ public class LeaderboardGroupConfigPanel extends AbstractEventPanel {
} }
private void updateGroup(final String oldGroupName, final LeaderboardGroupDTO groupToUpdate) { private void updateGroup(final String oldGroupName, final LeaderboardGroupDTO groupToUpdate) {
sailingService.updateLeaderboardGroup(oldGroupName, groupToUpdate.name, groupToUpdate.description, groupToUpdate.leaderboards, new AsyncCallback<Void>() { List<String> leaderboardNames = new ArrayList<String>();
for (LeaderboardDTO leaderboardDTO : groupToUpdate.leaderboards) {
leaderboardNames.add(leaderboardDTO.name);
}
sailingService.updateLeaderboardGroup(oldGroupName, groupToUpdate.name, groupToUpdate.description,
leaderboardNames, new AsyncCallback<Void>() {
@Override @Override
public void onFailure(Throwable t) { public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to update leaderboard group " + oldGroupName + ": " errorReporter.reportError("Error trying to update leaderboard group " + oldGroupName + ": "
@@ -11,6 +11,8 @@ public class DetailTypeFormatter {
return stringMessages.averageSpeedInKnots(); return stringMessages.averageSpeedInKnots();
case RANK_GAIN: case RANK_GAIN:
return stringMessages.rankGain(); return stringMessages.rankGain();
case RACE_RANK:
return stringMessages.rank();
case NUMBER_OF_MANEUVERS: case NUMBER_OF_MANEUVERS:
return stringMessages.numberOfManeuvers(); return stringMessages.numberOfManeuvers();
case CURRENT_SPEED_OVER_GROUND_IN_KNOTS: case CURRENT_SPEED_OVER_GROUND_IN_KNOTS:
@@ -10,6 +10,7 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.EventAndRaceIdentifier; import com.sap.sailing.domain.common.EventAndRaceIdentifier;
import com.sap.sailing.domain.common.EventIdentifier; import com.sap.sailing.domain.common.EventIdentifier;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSource;
@@ -122,10 +123,11 @@ public interface SailingService extends RemoteService {
void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Integer carriedPoints); void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Integer carriedPoints);
/** /**
* @return the new net points in {@link Pair#getA()} and the new total points in {@link Pair#getB()} * @return the new net points in {@link Pair#getA()} and the new total points in {@link Pair#getB()} for time point
* <code>date</code> after the max points reason has been updated to <code>maxPointsReasonAsString</code>.
*/ */
Pair<Integer, Integer> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, Pair<Integer, Integer> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString,
String raceColumnName, String maxPointsReasonAsString, Date date) throws NoWindException; String raceColumnName, MaxPointsReason maxPointsReason, Date date) throws NoWindException;
Pair<Integer, Integer> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString, Pair<Integer, Integer> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString,
String raceName, Integer correctedScore, Date date) throws NoWindException; String raceName, Integer correctedScore, Date date) throws NoWindException;
@@ -167,7 +169,7 @@ public interface SailingService extends RemoteService {
LeaderboardGroupDTO createLeaderboardGroup(String groupName, String description); LeaderboardGroupDTO createLeaderboardGroup(String groupName, String description);
void updateLeaderboardGroup(String oldName, String newName, String description, List<LeaderboardDTO> leaderboards); void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames);
MultiCompetitorRaceDataDTO getCompetitorsRaceData(RaceIdentifier race, List<Pair<Date, CompetitorDTO>> competitors, MultiCompetitorRaceDataDTO getCompetitorsRaceData(RaceIdentifier race, List<Pair<Date, CompetitorDTO>> competitors,
Date toDate, long stepSize, DetailType detailType) Date toDate, long stepSize, DetailType detailType)
@@ -9,6 +9,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.EventAndRaceIdentifier; import com.sap.sailing.domain.common.EventAndRaceIdentifier;
import com.sap.sailing.domain.common.EventIdentifier; import com.sap.sailing.domain.common.EventIdentifier;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Pair;
@@ -209,7 +210,7 @@ public interface SailingServiceAsync {
void updateLeaderboardCarryValue(String leaderboardName, String competitorID, Integer carriedPoints, AsyncCallback<Void> callback); void updateLeaderboardCarryValue(String leaderboardName, String competitorID, Integer carriedPoints, AsyncCallback<Void> callback);
void updateLeaderboardMaxPointsReason(String leaderboardName, String competitorID, String raceColumnName, void updateLeaderboardMaxPointsReason(String leaderboardName, String competitorID, String raceColumnName,
String maxPointsReasonAsString, Date date, AsyncCallback<Pair<Integer, Integer>> asyncCallback); MaxPointsReason maxPointsReason, Date date, AsyncCallback<Pair<Integer, Integer>> asyncCallback);
void updateLeaderboardScoreCorrection(String leaderboardName, String competitorID, String raceName, void updateLeaderboardScoreCorrection(String leaderboardName, String competitorID, String raceName,
Integer correctedScore, Date date, AsyncCallback<Pair<Integer, Integer>> asyncCallback); Integer correctedScore, Date date, AsyncCallback<Pair<Integer, Integer>> asyncCallback);
@@ -289,9 +290,9 @@ public interface SailingServiceAsync {
* @param oldName The old name of the group * @param oldName The old name of the group
* @param newName The new name of the group * @param newName The new name of the group
* @param description The new description of the group * @param description The new description of the group
* @param leaderboards The new leaderboards of the group * @param leaderboardNames The list of names of the new leaderboards of the group
*/ */
void updateLeaderboardGroup(String oldName, String newName, String description, List<LeaderboardDTO> leaderboards, AsyncCallback<Void> callback); void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames, AsyncCallback<Void> callback);
/** /**
* Returns the mark passings and the data for the given {@link DetailType} of all competitors in * Returns the mark passings and the data for the given {@link DetailType} of all competitors in
@@ -73,27 +73,27 @@ import com.sap.sailing.gwt.ui.shared.panels.SimpleBusyIndicator;
*/ */
public abstract class AbstractChartPanel<SettingsType extends ChartSettings> extends SimpleChartPanel public abstract class AbstractChartPanel<SettingsType extends ChartSettings> extends SimpleChartPanel
implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeListener, RequiresResize { implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeListener, RequiresResize {
protected static final int LINE_WIDTH = 1; private static final int LINE_WIDTH = 1;
protected MultiCompetitorRaceDataDTO chartData; private MultiCompetitorRaceDataDTO chartData;
protected final SailingServiceAsync sailingService; private final SailingServiceAsync sailingService;
protected final AsyncActionsExecutor asyncActionsExecutor; private final AsyncActionsExecutor asyncActionsExecutor;
protected final ErrorReporter errorReporter; private final ErrorReporter errorReporter;
protected Chart chart; private Chart chart;
private boolean compactChart; private boolean compactChart;
protected final AbsolutePanel busyIndicatorPanel; private final AbsolutePanel busyIndicatorPanel;
protected final Label noCompetitorsSelectedLabel; private final Label noCompetitorsSelectedLabel;
protected final Map<CompetitorDTO, Series> dataSeriesByCompetitor; private final Map<CompetitorDTO, Series> dataSeriesByCompetitor;
protected final Map<CompetitorDTO, Series> markPassingSeriesByCompetitor; private final Map<CompetitorDTO, Series> markPassingSeriesByCompetitor;
private Series timeLineSeries; private Series timeLineSeries;
private boolean timeLineNeedsUpdate = true; private boolean timeLineNeedsUpdate = true;
private final boolean allowTimeAdjust; private final boolean allowTimeAdjust;
private boolean ignoreTimeAdjustOnce; private boolean ignoreTimeAdjustOnce;
protected final RaceSelectionProvider raceSelectionProvider; private final RaceSelectionProvider raceSelectionProvider;
protected long stepSize = 5000; private long stepSize = 5000;
protected final StringMessages stringMessages; protected final StringMessages stringMessages;
protected final DateTimeFormat dateFormat = DateTimeFormat.getFormat("HH:mm:ss"); private final DateTimeFormat dateFormat = DateTimeFormat.getFormat("HH:mm:ss");
protected DetailType dataToShow; private DetailType dataToShow;
protected final CompetitorSelectionProvider competitorSelectionProvider; private final CompetitorSelectionProvider competitorSelectionProvider;
public AbstractChartPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, public AbstractChartPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
CompetitorSelectionProvider competitorSelectionProvider, RaceSelectionProvider raceSelectionProvider, CompetitorSelectionProvider competitorSelectionProvider, RaceSelectionProvider raceSelectionProvider,
@@ -24,9 +24,10 @@ import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent;
* *
*/ */
public class MultiChartPanel extends AbstractChartPanel<MultiChartSettings> implements Component<MultiChartSettings> { public class MultiChartPanel extends AbstractChartPanel<MultiChartSettings> implements Component<MultiChartSettings> {
public MultiChartPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, CompetitorSelectionProvider competitorSelectionProvider, public MultiChartPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
RaceSelectionProvider raceSelectionProvider, Timer timer, final StringMessages stringMessages, CompetitorSelectionProvider competitorSelectionProvider, RaceSelectionProvider raceSelectionProvider,
ErrorReporter errorReporter, boolean compactChart, boolean allowTimeAdjust) { Timer timer, final StringMessages stringMessages, ErrorReporter errorReporter, boolean compactChart,
boolean allowTimeAdjust) {
super(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider, timer, stringMessages, errorReporter, super(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider, timer, stringMessages, errorReporter,
/*show initially*/ DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER, compactChart, allowTimeAdjust); /*show initially*/ DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER, compactChart, allowTimeAdjust);
} }
@@ -28,7 +28,8 @@ public class MultiChartSettingsComponent extends AbstractChartSettingsComponent<
dataSelection = dialog.createListBox(/* isMultiSelect */ false); dataSelection = dialog.createListBox(/* isMultiSelect */ false);
int i=0; int i=0;
for (DetailType detailType : new DetailType[] { DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER, DetailType.DISTANCE_TRAVELED, for (DetailType detailType : new DetailType[] { DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER, DetailType.DISTANCE_TRAVELED,
DetailType.VELOCITY_MADE_GOOD_IN_KNOTS, DetailType.GAP_TO_LEADER_IN_SECONDS, DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS }) { DetailType.VELOCITY_MADE_GOOD_IN_KNOTS, DetailType.GAP_TO_LEADER_IN_SECONDS, DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS,
DetailType.RACE_RANK }) {
dataSelection.addItem(DetailTypeFormatter.format(detailType, getStringMessages()), detailType.toString()); dataSelection.addItem(DetailTypeFormatter.format(detailType, getStringMessages()), detailType.toString());
if (detailType == initialDataToShow) { if (detailType == initialDataToShow) {
dataSelection.setSelectedIndex(i); dataSelection.setSelectedIndex(i);
@@ -1,7 +1,6 @@
package com.sap.sailing.gwt.ui.leaderboardedit; package com.sap.sailing.gwt.ui.leaderboardedit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -13,6 +12,7 @@ import com.google.gwt.cell.client.HasCell;
import com.google.gwt.cell.client.SelectionCell; import com.google.gwt.cell.client.SelectionCell;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor; import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel; import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
@@ -143,7 +143,12 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
public MaxPointsDropDownCellProvider(String raceName) { public MaxPointsDropDownCellProvider(String raceName) {
this.raceName = raceName; this.raceName = raceName;
dropDownCell = new SelectionCell(Arrays.asList(new String[] { "", "DNS", "DNF", "OCS", "DND", "RAF", "BFD", "DNC", "DSQ" })); List<String> selectionCellContents = new ArrayList<String>();
selectionCellContents.add(""); // represents "no" max points reason
for (MaxPointsReason maxPointReason : MaxPointsReason.values()) {
selectionCellContents.add(maxPointReason.name());
}
dropDownCell = new SelectionCell(selectionCellContents);
} }
@Override @Override
@@ -160,7 +165,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
EditableLeaderboardPanel.this.getData()); EditableLeaderboardPanel.this.getData());
getWhiteboardOwner().whiteboardProduced(whiteboard); getWhiteboardOwner().whiteboardProduced(whiteboard);
getSailingService().updateLeaderboardMaxPointsReason(getLeaderboardName(), row.competitor.id, getSailingService().updateLeaderboardMaxPointsReason(getLeaderboardName(), row.competitor.id,
raceName, value == null || value.trim().length() == 0 ? null : value.trim(), raceName, value == null || value.trim().length() == 0 ? null : MaxPointsReason.valueOf(value.trim()),
getLeaderboardDisplayDate(), new AsyncCallback<Pair<Integer, Integer>>() { getLeaderboardDisplayDate(), new AsyncCallback<Pair<Integer, Integer>>() {
@Override @Override
public void onFailure(Throwable t) { public void onFailure(Throwable t) {
@@ -58,6 +58,7 @@ import com.sap.sailing.domain.common.EventIdentifier;
import com.sap.sailing.domain.common.EventName; import com.sap.sailing.domain.common.EventName;
import com.sap.sailing.domain.common.EventNameAndRaceName; import com.sap.sailing.domain.common.EventNameAndRaceName;
import com.sap.sailing.domain.common.LegType; import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.NoWindError; import com.sap.sailing.domain.common.NoWindError;
import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Placemark; import com.sap.sailing.domain.common.Placemark;
@@ -80,7 +81,6 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.Leaderboard.Entry; import com.sap.sailing.domain.leaderboard.Leaderboard.Entry;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup; import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection.MaxPointsReason;
import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl; import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
import com.sap.sailing.domain.persistence.DomainObjectFactory; import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory; import com.sap.sailing.domain.persistence.MongoObjectFactory;
@@ -522,9 +522,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
@Override @Override
public void removeAndUntrackRace(EventAndRaceIdentifier eventAndRaceidentifier) throws Exception{ public void removeAndUntrackRace(EventAndRaceIdentifier eventAndRaceidentifier) throws Exception{
Event event = getEvent(eventAndRaceidentifier); Event event = getEvent(eventAndRaceidentifier);
if(event!= null) { if (event!= null) {
RaceDefinition race = getRace(eventAndRaceidentifier); RaceDefinition race = getRace(eventAndRaceidentifier);
if(race != null) { if (race != null) {
getService().removeRace(event, race); getService().removeRace(event, race);
} }
} }
@@ -1269,13 +1269,13 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
} }
@Override @Override
public void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThreasholds) { public void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThresholds) {
if (!leaderboardName.equals(newLeaderboardName)) { if (!leaderboardName.equals(newLeaderboardName)) {
getService().renameLeaderboard(leaderboardName, newLeaderboardName); getService().renameLeaderboard(leaderboardName, newLeaderboardName);
} }
Leaderboard leaderboard = getService().getLeaderboardByName(newLeaderboardName); Leaderboard leaderboard = getService().getLeaderboardByName(newLeaderboardName);
if (!Arrays.equals(leaderboard.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces(), newDiscardingThreasholds)) { if (!Arrays.equals(leaderboard.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces(), newDiscardingThresholds)) {
leaderboard.setResultDiscardingRule(new ResultDiscardingRuleImpl(newDiscardingThreasholds)); leaderboard.setResultDiscardingRule(new ResultDiscardingRuleImpl(newDiscardingThresholds));
} }
getService().updateStoredLeaderboard(leaderboard); getService().updateStoredLeaderboard(leaderboard);
} }
@@ -1381,7 +1381,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
@Override @Override
public Pair<Integer, Integer> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName, public Pair<Integer, Integer> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName,
String maxPointsReasonAsString, Date date) throws NoWindException { MaxPointsReason maxPointsReason, Date date) throws NoWindException {
TimePoint timePoint = new MillisecondsTimePoint(date); TimePoint timePoint = new MillisecondsTimePoint(date);
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName); Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
if (leaderboard != null) { if (leaderboard != null) {
@@ -1391,11 +1391,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
if (raceColumn == null) { if (raceColumn == null) {
throw new IllegalArgumentException("Didn't find race "+raceColumnName+" in leaderboard "+leaderboardName); throw new IllegalArgumentException("Didn't find race "+raceColumnName+" in leaderboard "+leaderboardName);
} }
if (maxPointsReasonAsString == null) { leaderboard.getScoreCorrection().setMaxPointsReason(competitor, raceColumn, maxPointsReason);
leaderboard.getScoreCorrection().setMaxPointsReason(competitor, raceColumn, null); // null means "unset"
} else {
leaderboard.getScoreCorrection().setMaxPointsReason(competitor, raceColumn, MaxPointsReason.valueOf(maxPointsReasonAsString));
}
getService().updateStoredLeaderboard(leaderboard); getService().updateStoredLeaderboard(leaderboard);
Entry updatedEntry = leaderboard.getEntry(competitor, raceColumn, timePoint); Entry updatedEntry = leaderboard.getEntry(competitor, raceColumn, timePoint);
return new Pair<Integer, Integer>(updatedEntry.getNetPoints(), updatedEntry.getTotalPoints()); return new Pair<Integer, Integer>(updatedEntry.getNetPoints(), updatedEntry.getTotalPoints());
@@ -1568,6 +1564,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
Distance distanceToLeader = trackedLeg.getWindwardDistanceToOverallLeader(timePoint); Distance distanceToLeader = trackedLeg.getWindwardDistanceToOverallLeader(timePoint);
result = (distanceToLeader == null) ? null : distanceToLeader.getMeters(); result = (distanceToLeader == null) ? null : distanceToLeader.getMeters();
break; break;
case RACE_RANK:
result = (double) trackedLeg.getRank(timePoint);
break;
} }
} }
return result; return result;
@@ -1740,10 +1739,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
@Override @Override
public TrackedRace getExistingTrackedRace(RaceIdentifier eventNameAndRaceName) { public TrackedRace getExistingTrackedRace(RaceIdentifier eventNameAndRaceName) {
Event event = getService().getEventByName(eventNameAndRaceName.getEventName()); return getService().getExistingTrackedRace(eventNameAndRaceName);
RaceDefinition race = getRaceByName(event, eventNameAndRaceName.getRaceName());
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getExistingTrackedRace(race);
return trackedRace;
} }
@Override @Override
@@ -1823,22 +1819,8 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
} }
@Override @Override
public void updateLeaderboardGroup(String oldName, String newName, String description, List<LeaderboardDTO> leaderboards) { public void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames) {
if (!oldName.equals(newName)) { getService().updateLeaderboardGroup(oldName, newName, description, leaderboardNames);
getService().renameLeaderboardGroup(oldName, newName);
}
LeaderboardGroup group = getService().getLeaderboardGroupByName(newName);
if (!description.equals(group.getDescription())) {
group.setDescriptiom(description);
}
group.clearLeaderboards();
for (LeaderboardDTO leaderboardDTO : leaderboards) {
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardDTO.name);
if (leaderboard != null) {
group.addLeaderboard(leaderboard);
}
}
getService().updateStoredLeaderboardGroup(group);
} }
} }
@@ -29,278 +29,299 @@ import com.sap.sailing.gwt.ui.shared.WindLatticeGenParamsDTO;
import java.util.logging.*; import java.util.logging.*;
public class SimulatorEntryPoint implements EntryPoint { public class SimulatorEntryPoint implements EntryPoint {
private final SimulatorServiceAsync simulatorSvc = GWT.create(SimulatorService.class); private final SimulatorServiceAsync simulatorSvc = GWT.create(SimulatorService.class);
private final VerticalPanel panel = new VerticalPanel(); private final VerticalPanel panel = new VerticalPanel();
private final ListBox raceSelector = new ListBox(); private final ListBox raceSelector = new ListBox();
private final CheckBox checkBox = new CheckBox("Show Grid"); private final CheckBox checkBox = new CheckBox("Show Grid");
private LatLng currentPoint; private LatLng currentPoint;
private MapWidget mapw; private MapWidget mapw;
private Polyline [] windlattice = new Polyline[0]; //private Polyline[] windlattice = new Polyline[0];
private List<PositionDTO> locations = new ArrayList<PositionDTO>(); private List<PositionDTO> locations = new ArrayList<PositionDTO>();
private static Logger logger = Logger.getLogger("com.sap.sailing"); private WindFieldCanvasOverlay windField;
private WindLatticeCanvasOverlay windLattice;
@Override private static Logger logger = Logger.getLogger("com.sap.sailing");
public void onModuleLoad() {
logger.fine("In onModuleLoad");
/*
* Asynchronously loads the Maps API.
*
* The first parameter should be a valid Maps API Key to deploy this
* application on a public server, but a blank key will work for an
* application served from localhost.
*/
Maps.loadMapsApi("", "2", false, new Runnable() {
public void run() {
buildUi();
}
});
}
private void buildUi() { @Override
logger.severe("Logger Name : " + logger.getName() + " Logging level " + logger.getLevel()); public void onModuleLoad() {
logger.fine("In buildUi"); logger.fine("In onModuleLoad");
loadRaceLocations(); /*
* Asynchronously loads the Maps API.
*
* The first parameter should be a valid Maps API Key to deploy this application on a public server, but a blank
* key will work for an application served from localhost.
*/
Maps.loadMapsApi("", "2", false, new Runnable() {
public void run() {
buildUi();
}
});
}
initMap(); private void buildUi() {
initRaceSelector(); logger.severe("Logger Name : " + logger.getName() + " Logging level " + logger.getLevel());
initDisplayOptions(); logger.fine("In buildUi");
initPanel(); loadRaceLocations();
// Add the map to the HTML host page initMap();
RootLayoutPanel.get().add(panel); initRaceSelector();
} initDisplayOptions();
initPanel();
private void initMap() {
logger.fine("In initMap");
mapw = new MapWidget();
mapw.setUI(SimulatorMapOptions.newInstance());
mapw.setZoomLevel(7);
mapw.setSize("100%", "650px");
mapw.addMapClickHandler(new MapClickHandler() {
@Override
public void onClick(MapClickEvent event) {
currentPoint = event.getLatLng();
generateWindLattice(currentPoint);
}
});
}
private void loadRaceLocations() { //windField = new WindFieldCanvasOverlay();
logger.fine("In loadRaceLocations"); //mapw.addOverlay(windField);
simulatorSvc.getRaceLocations(new AsyncCallback<PositionDTO[]>() {
@Override
public void onFailure(Throwable caught) {
String message = caught.getMessage();
for( StackTraceElement ste : caught.getStackTrace() ) {
message += ste.toString() + "\n\t";
}
Window.alert("Failed servlet call to SimulatorService\n" + message);
}
@Override windLattice = new WindLatticeCanvasOverlay();
public void onSuccess(PositionDTO[] result) { mapw.addOverlay(windLattice);
locations.clear();
int i = 0;
for( PositionDTO rl : result ) {
locations.add(rl);
raceSelector.addItem(Integer.toString(++i));
}
}
});
}
private void initRaceSelector() { // Add the map to the HTML host page
logger.fine("In initRaceSelector"); RootLayoutPanel.get().add(panel);
raceSelector.setVisibleItemCount(1);
raceSelector.setTitle("Race Location Selection");
raceSelector.setSize("100%", "20px");
raceSelector.addClickHandler(new ClickHandler() { if (locations != null && locations.size() > 0) {
@Override selectRaceLocation(locations.get(0));
public void onClick(ClickEvent event) { }
PositionDTO rl = locations.get(raceSelector.getSelectedIndex()); }
selectRaceLocation(rl);
}
});
}
private void initPanel() { private void initMap() {
logger.fine("In initPanel"); logger.fine("In initMap");
panel.add(raceSelector); mapw = new MapWidget();
panel.add(checkBox); mapw.setUI(SimulatorMapOptions.newInstance());
panel.add(mapw); mapw.setZoomLevel(7);
panel.setSize("100%", "100%"); mapw.setSize("100%", "650px");
}
private void selectRaceLocation(PositionDTO rl) { mapw.addMapClickHandler(new MapClickHandler() {
logger.fine("In selectRaceLocation"); @Override
mapw.clearOverlays(); public void onClick(MapClickEvent event) {
LatLng position = LatLng.newInstance(rl.latDeg, rl.lngDeg); currentPoint = event.getLatLng();
mapw.panTo(position); generateWindLattice(currentPoint);
}
private void generateWindLattice(LatLng center) { //windField.setPosition(currentPoint);
if (center != null) { //windField.redraw(true);
logger.info("In generateWindLattice with center " + center.getLatitude() + " " + center.getLongitude()); }
} else { });
logger.info("Center is null"); }
return;
}
WindLatticeGenParamsDTO params = new WindLatticeGenParamsDTO();
params.setCenter(new PositionDTO(center.getLatitude(), center.getLongitude()));
params.setGridsizeX(5);
params.setGridsizeY(5);
params.setxSize(1);
params.setySize(1);
simulatorSvc.getWindLatice(params, new AsyncCallback<WindLatticeDTO>(){ private void loadRaceLocations() {
@Override logger.fine("In loadRaceLocations");
public void onFailure(Throwable message) { simulatorSvc.getRaceLocations(new AsyncCallback<PositionDTO[]>() {
Window.alert("Failed servlet call to SimulatorService\n" + message); @Override
} public void onFailure(Throwable caught) {
@Override String message = caught.getMessage();
public void onSuccess(WindLatticeDTO wl) { for (StackTraceElement ste : caught.getStackTrace()) {
refreshWindLattice(wl); message += ste.toString() + "\n\t";
} }
}); Window.alert("Failed servlet call to SimulatorService\n" + message);
} }
private void refreshWindLattice(WindLatticeDTO wl) { @Override
logger.fine("In refereshWindLattice"); public void onSuccess(PositionDTO[] result) {
PositionDTO [][] matrix = wl.getMatrix(); locations.clear();
mapw.clearOverlays(); int i = 0;
if (checkBox.getValue()) { for (PositionDTO rl : result) {
int numRows = matrix.length; locations.add(rl);
raceSelector.addItem(Integer.toString(++i));
}
}
});
}
int numCols = matrix[0].length; private void initRaceSelector() {
logger.fine("Numrows : " + numRows + " Numcols : " + numCols); logger.fine("In initRaceSelector");
int line = 0; raceSelector.setVisibleItemCount(1);
raceSelector.setTitle("Race Location Selection");
raceSelector.setSize("100%", "20px");
Polyline [] newWindLattice = new Polyline[numRows + numCols];
for( int i = 0; i < numRows; i++ ) { raceSelector.addClickHandler(new ClickHandler() {
LatLng [] points = new LatLng[numCols]; @Override
for( int j = 0; j < numCols; j++ ) { public void onClick(ClickEvent event) {
points[j] = LatLng.newInstance(matrix[i][j].latDeg, matrix[i][j].lngDeg); PositionDTO rl = locations.get(raceSelector.getSelectedIndex());
} selectRaceLocation(rl);
newWindLattice[line++] = new Polyline(points, "#000000", 1); }
} });
}
for( int i = 0; i < numCols; i++ ) { private void initPanel() {
LatLng [] points = new LatLng[numRows]; logger.fine("In initPanel");
for( int j = 0; j < numRows; j++ ) { panel.add(raceSelector);
points[j] = LatLng.newInstance(matrix[j][i].latDeg, matrix[j][i].lngDeg); panel.add(checkBox);
} panel.add(mapw);
newWindLattice[line++] = new Polyline(points, "#000000", 1); panel.setSize("100%", "100%");
} }
for( Polyline pl : newWindLattice ) {
this.mapw.addOverlay(pl);
}
}
generateWindDirection(wl);
}
private void generateWindDirection(WindLatticeDTO wl) { private void selectRaceLocation(PositionDTO rl) {
logger.fine("In generateWindDirection"); logger.fine("In selectRaceLocation");
PositionDTO [][] matrix = wl.getMatrix(); //mapw.clearOverlays();
int numRows = matrix.length; LatLng position = LatLng.newInstance(rl.latDeg, rl.lngDeg);
int numCols = matrix[0].length; mapw.panTo(position);
//addArrow(matrix[0][0], matrix[1][1]); }
if (numRows > 0 && numCols > 0) {
LatLng start = LatLng.newInstance(matrix[0][0].latDeg, matrix[0][0].lngDeg);
LatLng end = LatLng.newInstance(matrix[1][1].latDeg, matrix[1][1].lngDeg);
Point sPoint = mapw.convertLatLngToContainerPixel(start);
Point ePoint = mapw.convertLatLngToContainerPixel(end);
double dx = ePoint.getX() - sPoint.getX();
double dy = ePoint.getY() - ePoint.getY();
double distance = Math.sqrt((dx*dx) + (dy*dy));
logger.fine("Distance : " + distance);
double theta = Math.PI - Math.PI/4; //Math.atan2(-dy,dx);
for(int i = 1; i < numRows; ++i) {
for (int j = 1; j < numCols; ++j) {
addArrow(matrix[i][j], theta, distance, (int) (0.5 + i*0.5));
}
} private void generateWindLattice(LatLng center) {
} if (center != null) {
} logger.info("In generateWindLattice with center " + center.getLatitude() + " " + center.getLongitude());
} else {
logger.info("Center is null");
return;
}
WindLatticeGenParamsDTO params = new WindLatticeGenParamsDTO();
params.setCenter(new PositionDTO(center.getLatitude(), center.getLongitude()));
params.setGridsizeX(5);
params.setGridsizeY(5);
params.setxSize(1);
params.setySize(1);
private void addArrow(PositionDTO start, PositionDTO end) { simulatorSvc.getWindLatice(params, new AsyncCallback<WindLatticeDTO>() {
LatLng[] arrowPoints = new LatLng[2]; @Override
arrowPoints[0] = LatLng.newInstance(start.latDeg, start.lngDeg); public void onFailure(Throwable message) {
arrowPoints[1] = LatLng.newInstance(end.latDeg, end.lngDeg); Window.alert("Failed servlet call to SimulatorService\n" + message);
}
Polyline arrow = new Polyline(arrowPoints, "Green", 1); @Override
this.mapw.addOverlay(arrow); public void onSuccess(WindLatticeDTO wl) {
double theta = Math.PI/4; windLattice.setPosition(currentPoint);
addHead(arrowPoints[1], theta, 1, 1); windLattice.setWindLattice(wl);
logger.info("In addArrow(start, end) arrowPoints[0]" + arrowPoints[0]); windLattice.redraw(true);
logger.info("In addArrow(start, end) arrowPoints[1]" + arrowPoints[1]); //refreshWindLattice(wl);
} }
});
}
private void addArrow(PositionDTO start, double angle, double length, int weight) { private void refreshWindLattice(WindLatticeDTO wl) {
logger.fine("In addArrow(start, angle, length)"); logger.fine("In refereshWindLattice");
LatLng[] arrowPoints = new LatLng[2]; PositionDTO[][] matrix = wl.getMatrix();
arrowPoints[0] = LatLng.newInstance(start.latDeg, start.lngDeg); //mapw.clearOverlays();
Point point = mapw.convertLatLngToContainerPixel(arrowPoints[0]); if (checkBox.getValue()) {
double x1 = point.getX() + length*Math.cos(angle); int numRows = matrix.length;
double y1 = point.getY() + length*Math.sin(angle);
LatLng end = mapw.convertContainerPixelToLatLng(Point.newInstance((int)x1, (int)y1));
arrowPoints[1] = LatLng.newInstance(end.getLatitude(), end.getLongitude()); int numCols = matrix[0].length;
Polyline arrow = new Polyline(arrowPoints, "Green", weight); logger.fine("Numrows : " + numRows + " Numcols : " + numCols);
this.mapw.addOverlay(arrow); int line = 0;
logger.fine("In addArrow(start, angle, length) arrowPoints[0]" + arrowPoints[0]);
logger.fine("In addArrow(start, angle, length) arrowPoints[1]" + arrowPoints[1]);
double dx = x1 - point.getX();
double dy = y1 - point.getY();
double theta = Math.atan2(-dy,dx);
addHead(arrowPoints[1], theta, length/20, weight);
}
private void addHead(LatLng point, double theta, double headLength, int weight) { Polyline[] newWindLattice = new Polyline[numRows + numCols];
logger.fine("In addHead");
//add an arrow head at the specified point
double t = theta + (Math.PI/4) ;
if(t > Math.PI)
t -= 2*Math.PI;
double t2 = theta - (Math.PI/4) ;
if(t2 <= (-Math.PI))
t2 += 2*Math.PI;
LatLng[] pts = new LatLng[3];
Point ppoint = mapw.convertLatLngToContainerPixel(point);
int x = ppoint.getX();
int y = ppoint.getY();
int x1 = (int) Math.round(x-Math.cos(t)*headLength);
int y1 = (int) Math.round(y+Math.sin(t)*headLength);
int x2 = (int) Math.round(x-Math.cos(t2)*headLength);
int y2 = (int) Math.round(y+Math.sin(t2)*headLength);
pts[0] = mapw.convertContainerPixelToLatLng(Point.newInstance(x1, y1));
pts[1] = mapw.convertContainerPixelToLatLng(Point.newInstance(x, y));
pts[2] = mapw.convertContainerPixelToLatLng(Point.newInstance(x2, y2));
Polyline polyline = new Polyline(pts, "Red", weight); for (int i = 0; i < numRows; i++) {
mapw.addOverlay(polyline); LatLng[] points = new LatLng[numCols];
} for (int j = 0; j < numCols; j++) {
points[j] = LatLng.newInstance(matrix[i][j].latDeg, matrix[i][j].lngDeg);
}
newWindLattice[line++] = new Polyline(points, "#000000", 1);
}
for (int i = 0; i < numCols; i++) {
LatLng[] points = new LatLng[numRows];
for (int j = 0; j < numRows; j++) {
points[j] = LatLng.newInstance(matrix[j][i].latDeg, matrix[j][i].lngDeg);
}
newWindLattice[line++] = new Polyline(points, "#000000", 1);
}
for (Polyline pl : newWindLattice) {
this.mapw.addOverlay(pl);
}
}
generateWindDirection(wl);
}
private void generateWindDirection(WindLatticeDTO wl) {
logger.fine("In generateWindDirection");
PositionDTO[][] matrix = wl.getMatrix();
int numRows = matrix.length;
int numCols = matrix[0].length;
// addArrow(matrix[0][0], matrix[1][1]);
if (numRows > 0 && numCols > 0) {
LatLng start = LatLng.newInstance(matrix[0][0].latDeg, matrix[0][0].lngDeg);
LatLng end = LatLng.newInstance(matrix[1][1].latDeg, matrix[1][1].lngDeg);
Point sPoint = mapw.convertLatLngToContainerPixel(start);
Point ePoint = mapw.convertLatLngToContainerPixel(end);
double dx = ePoint.getX() - sPoint.getX();
double dy = ePoint.getY() - ePoint.getY();
double distance = Math.sqrt((dx * dx) + (dy * dy));
logger.fine("Distance : " + distance);
double theta = Math.PI - Math.PI / 4; // Math.atan2(-dy,dx);
for (int i = 1; i < numRows; ++i) {
for (int j = 1; j < numCols; ++j) {
addArrow(matrix[i][j], theta, distance, (int) (0.5 + i * 0.5));
}
}
}
}
private void addArrow(PositionDTO start, PositionDTO end) {
LatLng[] arrowPoints = new LatLng[2];
arrowPoints[0] = LatLng.newInstance(start.latDeg, start.lngDeg);
arrowPoints[1] = LatLng.newInstance(end.latDeg, end.lngDeg);
Polyline arrow = new Polyline(arrowPoints, "Green", 1);
this.mapw.addOverlay(arrow);
double theta = Math.PI / 4;
addHead(arrowPoints[1], theta, 1, 1);
logger.info("In addArrow(start, end) arrowPoints[0]" + arrowPoints[0]);
logger.info("In addArrow(start, end) arrowPoints[1]" + arrowPoints[1]);
}
private void addArrow(PositionDTO start, double angle, double length, int weight) {
logger.fine("In addArrow(start, angle, length)");
LatLng[] arrowPoints = new LatLng[2];
arrowPoints[0] = LatLng.newInstance(start.latDeg, start.lngDeg);
Point point = mapw.convertLatLngToContainerPixel(arrowPoints[0]);
double x1 = point.getX() + length * Math.cos(angle);
double y1 = point.getY() + length * Math.sin(angle);
LatLng end = mapw.convertContainerPixelToLatLng(Point.newInstance((int) x1, (int) y1));
arrowPoints[1] = LatLng.newInstance(end.getLatitude(), end.getLongitude());
Polyline arrow = new Polyline(arrowPoints, "Green", weight);
this.mapw.addOverlay(arrow);
logger.fine("In addArrow(start, angle, length) arrowPoints[0]" + arrowPoints[0]);
logger.fine("In addArrow(start, angle, length) arrowPoints[1]" + arrowPoints[1]);
double dx = x1 - point.getX();
double dy = y1 - point.getY();
double theta = Math.atan2(-dy, dx);
addHead(arrowPoints[1], theta, length / 20, weight);
}
private void addHead(LatLng point, double theta, double headLength, int weight) {
logger.fine("In addHead");
// add an arrow head at the specified point
double t = theta + (Math.PI / 4);
if (t > Math.PI)
t -= 2 * Math.PI;
double t2 = theta - (Math.PI / 4);
if (t2 <= (-Math.PI))
t2 += 2 * Math.PI;
LatLng[] pts = new LatLng[3];
Point ppoint = mapw.convertLatLngToContainerPixel(point);
int x = ppoint.getX();
int y = ppoint.getY();
int x1 = (int) Math.round(x - Math.cos(t) * headLength);
int y1 = (int) Math.round(y + Math.sin(t) * headLength);
int x2 = (int) Math.round(x - Math.cos(t2) * headLength);
int y2 = (int) Math.round(y + Math.sin(t2) * headLength);
pts[0] = mapw.convertContainerPixelToLatLng(Point.newInstance(x1, y1));
pts[1] = mapw.convertContainerPixelToLatLng(Point.newInstance(x, y));
pts[2] = mapw.convertContainerPixelToLatLng(Point.newInstance(x2, y2));
Polyline polyline = new Polyline(pts, "Red", weight);
mapw.addOverlay(polyline);
}
private void initDisplayOptions() { private void initDisplayOptions() {
logger.fine("In initDisplayOptions"); logger.fine("In initDisplayOptions");
checkBox.setSize("100%", "20px"); checkBox.setSize("100%", "20px");
checkBox.setTitle("Grid Selector"); checkBox.setTitle("Grid Selector");
checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() { checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override @Override
public void onValueChange(ValueChangeEvent<Boolean> event) { public void onValueChange(ValueChangeEvent<Boolean> event) {
generateWindLattice(currentPoint); generateWindLattice(currentPoint);
} }
}); });
/*if (checkBox.length > 1) { /*
checkBox[0].setText("Grid"); * if (checkBox.length > 1) { checkBox[0].setText("Grid"); checkBox[1].setText("Wind Direction"); }
checkBox[1].setText("Wind Direction"); */
}*/ }
}
} }
@@ -4,36 +4,36 @@ import com.google.gwt.maps.client.MapUIOptions;
import com.google.gwt.maps.client.geom.Size; import com.google.gwt.maps.client.geom.Size;
public class SimulatorMapOptions { public class SimulatorMapOptions {
private final static int width = 500; private final static int width = 500;
private final static int height = 300; private final static int height = 300;
private final static boolean doubleClick = true; private final static boolean doubleClick = true;
private final static boolean hybridMapType = false; private final static boolean hybridMapType = false;
private final static boolean keyboard = false; private final static boolean keyboard = false;
private final static boolean largeMapControl3d = false; private final static boolean largeMapControl3d = false;
private final static boolean mapTypeControl = false; private final static boolean mapTypeControl = false;
private final static boolean menuMapTypeControl = false; private final static boolean menuMapTypeControl = false;
private final static boolean normalMapType = true; private final static boolean normalMapType = true;
private final static boolean physicalMapType = false; private final static boolean physicalMapType = false;
private final static boolean satelliteMapType = false; private final static boolean satelliteMapType = false;
private final static boolean scaleControl = true; private final static boolean scaleControl = true;
private final static boolean scrollwheel = true; private final static boolean scrollwheel = true;
private final static boolean smallZoomControl3d = true; private final static boolean smallZoomControl3d = true;
public static MapUIOptions newInstance() { public static MapUIOptions newInstance() {
MapUIOptions mapOptions = MapUIOptions.newInstance(Size.newInstance(width, height)); MapUIOptions mapOptions = MapUIOptions.newInstance(Size.newInstance(width, height));
mapOptions.setDoubleClick(doubleClick); mapOptions.setDoubleClick(doubleClick);
mapOptions.setHybridMapType(hybridMapType); mapOptions.setHybridMapType(hybridMapType);
mapOptions.setKeyboard(keyboard); mapOptions.setKeyboard(keyboard);
mapOptions.setLargeMapControl3d(largeMapControl3d); mapOptions.setLargeMapControl3d(largeMapControl3d);
mapOptions.setMapTypeControl(mapTypeControl); mapOptions.setMapTypeControl(mapTypeControl);
mapOptions.setMenuMapTypeControl(menuMapTypeControl); mapOptions.setMenuMapTypeControl(menuMapTypeControl);
mapOptions.setNormalMapType(normalMapType); mapOptions.setNormalMapType(normalMapType);
mapOptions.setPhysicalMapType(physicalMapType); mapOptions.setPhysicalMapType(physicalMapType);
mapOptions.setSatelliteMapType(satelliteMapType); mapOptions.setSatelliteMapType(satelliteMapType);
mapOptions.setScaleControl(scaleControl); mapOptions.setScaleControl(scaleControl);
mapOptions.setScrollwheel(scrollwheel); mapOptions.setScrollwheel(scrollwheel);
mapOptions.setSmallZoomControl3d(smallZoomControl3d); mapOptions.setSmallZoomControl3d(smallZoomControl3d);
return mapOptions; return mapOptions;
} }
} }
@@ -17,10 +17,6 @@
<!-- Google Maps API --> <!-- Google Maps API -->
<inherits name='com.google.gwt.maps.GoogleMaps' /> <inherits name='com.google.gwt.maps.GoogleMaps' />
<!-- Flot-Gwt API -->
<!-- <inherits name='ca.nanometrics.gflot.GFlot'/> -->
<!-- <inherits name="org.moxieapps.gwt.highcharts.Highcharts" />-->
<!-- Other module inherits --> <!-- Other module inherits -->
<inherits name="com.sap.sailing.domain.SailingDomain" /> <inherits name="com.sap.sailing.domain.SailingDomain" />
@@ -16,10 +16,10 @@ import com.sap.sailing.domain.base.impl.CompetitorImpl;
import com.sap.sailing.domain.base.impl.NationalityImpl; import com.sap.sailing.domain.base.impl.NationalityImpl;
import com.sap.sailing.domain.base.impl.PersonImpl; import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.TeamImpl; import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard; import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
import com.sap.sailing.domain.leaderboard.ScoreCorrection;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardImpl; import com.sap.sailing.domain.leaderboard.impl.LeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl; import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl; import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
@@ -97,7 +97,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
final String leaderboardName = "TestLeaderboard"; final String leaderboardName = "TestLeaderboard";
final String raceColumnName1 = "My First Race 1"; final String raceColumnName1 = "My First Race 1";
final String raceColumnName2 = "My First Race 2"; final String raceColumnName2 = "My First Race 2";
final ScoreCorrection.MaxPointsReason maxPointsReason = ScoreCorrection.MaxPointsReason.DNF; final MaxPointsReason maxPointsReason = MaxPointsReason.DNF;
final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 }; final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 };
LeaderboardImpl leaderboard = new LeaderboardImpl(leaderboardName, new ScoreCorrectionImpl(), LeaderboardImpl leaderboard = new LeaderboardImpl(leaderboardName, new ScoreCorrectionImpl(),
new ResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces)); new ResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces));
@@ -124,7 +124,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
final String raceColumnName1 = "My First Race 1"; final String raceColumnName1 = "My First Race 1";
final String raceColumnName2 = "My First Race 2"; final String raceColumnName2 = "My First Race 2";
final int correctedPoints = 2; final int correctedPoints = 2;
final ScoreCorrection.MaxPointsReason maxPointsReason = ScoreCorrection.MaxPointsReason.DNF; final MaxPointsReason maxPointsReason = MaxPointsReason.DNF;
final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 }; final int[] discardIndexResultsStartingWithHowManyRaces = new int[] { 5, 8 };
LeaderboardImpl leaderboard = new LeaderboardImpl(leaderboardName, new ScoreCorrectionImpl(), LeaderboardImpl leaderboard = new LeaderboardImpl(leaderboardName, new ScoreCorrectionImpl(),
new ResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces)); new ResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces));
@@ -18,7 +18,7 @@ import com.sap.sailing.operationaltransformation.PeerImpl;
import com.sap.sailing.server.RacingEventService; import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.impl.RacingEventServiceImpl; import com.sap.sailing.server.impl.RacingEventServiceImpl;
import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard; import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard;
import com.sap.sailing.server.operationaltransformation.AddLeaderboard; import com.sap.sailing.server.operationaltransformation.CreateLeaderboard;
import com.sap.sailing.server.operationaltransformation.MoveLeaderboardColumnUp; import com.sap.sailing.server.operationaltransformation.MoveLeaderboardColumnUp;
import com.sap.sailing.server.operationaltransformation.OperationalTransformer; import com.sap.sailing.server.operationaltransformation.OperationalTransformer;
import com.sap.sailing.server.operationaltransformation.RacingEventServiceOperation; import com.sap.sailing.server.operationaltransformation.RacingEventServiceOperation;
@@ -48,7 +48,7 @@ public class OperationalTransformationTest {
@Test @Test
public void testAddLeaderboard() { public void testAddLeaderboard() {
RacingEventServiceOperation addLeaderboardOp = new AddLeaderboard(LEADERBOARDNAME, new int[] { 5 }); RacingEventServiceOperation addLeaderboardOp = new CreateLeaderboard(LEADERBOARDNAME, new int[] { 5 });
server.apply(addLeaderboardOp); server.apply(addLeaderboardOp);
server.waitForNotRunning(); server.waitForNotRunning();
replica.waitForNotRunning(); replica.waitForNotRunning();
@@ -326,4 +326,6 @@ public interface RacingEventService extends TrackedEventRegistry {
*/ */
void addRace(EventIdentifier addToEvent, RaceDefinition raceDefinition); void addRace(EventIdentifier addToEvent, RaceDefinition raceDefinition);
void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames);
} }
@@ -779,7 +779,10 @@ public class RacingEventServiceImpl implements RacingEventService, EventFetcher,
@Override @Override
public TrackedRace getExistingTrackedRace(RaceIdentifier raceIdentifier) { public TrackedRace getExistingTrackedRace(RaceIdentifier raceIdentifier) {
return (TrackedRace) raceIdentifier.getExistingTrackedRace(this); Event event = getEventByName(raceIdentifier.getEventName());
RaceDefinition race = event.getRaceByName(raceIdentifier.getRaceName());
TrackedRace trackedRace = getOrCreateTrackedEvent(event).getExistingTrackedRace(race);
return trackedRace;
} }
@Override @Override
@@ -859,6 +862,25 @@ public class RacingEventServiceImpl implements RacingEventService, EventFetcher,
} }
} }
@Override
public void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames) {
if (!oldName.equals(newName)) {
renameLeaderboardGroup(oldName, newName);
}
LeaderboardGroup group = getLeaderboardGroupByName(newName);
if (!description.equals(group.getDescription())) {
group.setDescriptiom(description);
}
group.clearLeaderboards();
for (String leaderboardName : leaderboardNames) {
Leaderboard leaderboard = getLeaderboardByName(leaderboardName);
if (leaderboard != null) {
group.addLeaderboard(leaderboard);
}
}
mongoObjectFactory.storeLeaderboardGroup(group);
}
@Override @Override
public void updateStoredLeaderboardGroup(LeaderboardGroup leaderboardGroup) { public void updateStoredLeaderboardGroup(LeaderboardGroup leaderboardGroup) {
mongoObjectFactory.storeLeaderboardGroup(leaderboardGroup); mongoObjectFactory.storeLeaderboardGroup(leaderboardGroup);
Loaded 100 of 122 files, more files were not shown because too many files have changed in this diff. Show more