mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-03 02:43:53 +00:00
Merge branch 'master' of ssh://195.227.10.246/home/trac/git
This commit is contained in:
commit
0bae880ae6
20 files changed
+268
-91
No files matched your search
@@ -1,18 +0,0 @@
|
||||
- Implement and test course update with corresponding TrackedLeg[OfCompetitor] updates
|
||||
|
||||
- Clarify Equinox server upgrade process from the maven-repository
|
||||
|
||||
- Open test server firewall ports for UDP / Expedition wind integration
|
||||
|
||||
- Set up two Expedition machines with RF and UMTS transmission, test killing one
|
||||
|
||||
- enable switching between our and TracTrac-provided leaderboard information
|
||||
|
||||
- Test fail-over in case one of the two Java VM fails
|
||||
|
||||
- Pass final production instance URL information to BeTomorrow for wind integration
|
||||
|
||||
- Display gain/loss for next-best competitor (green/red arrow up/down) based on VMG comparison
|
||||
|
||||
- Improve Mongo-based tests by using Mongo transactions instead of waiting for prior transactions to complete
|
||||
|
||||
@@ -83,5 +83,6 @@ public class CourseUpdateTest extends AbstractTracTracLiveTest {
|
||||
@Test
|
||||
public void testLastWaypointRemoved() {
|
||||
Iterable<Waypoint> waypoints = course.getWaypoints();
|
||||
// TODO continue with testLastWaypointRemoved()...
|
||||
}
|
||||
}
|
||||
+3
@@ -66,6 +66,9 @@ public class ReceiveTrackingDataTest extends AbstractTracTracLiveTest {
|
||||
@Override
|
||||
public void windDataReceived(Wind wind) {
|
||||
}
|
||||
@Override
|
||||
public void windDataRemoved(Wind wind) {
|
||||
}
|
||||
};
|
||||
List<TypeController> listeners = new ArrayList<TypeController>();
|
||||
Event event = domainFactory.createEvent(getEvent());
|
||||
|
||||
Executable → Regular
+35
@@ -2,8 +2,12 @@ package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
import com.sap.sailing.domain.base.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
@@ -77,4 +81,35 @@ public class WindTest {
|
||||
assertEquals(10, estimate.getKnots(), 0.000000001);
|
||||
assertEquals(105, estimate.getBearing().getDegrees(), 0.00000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsingNewerThanRequestedIfCloserThanOlder() throws ParseException {
|
||||
/*
|
||||
Imagine the following wind measurements:
|
||||
|
||||
2009-07-11T13:45:00.000+0200@null: 10.0kn from 278.0� avg(30000ms): 2009-07-11T13:45:00.000+0200@null: 10.0kn from 278.0�
|
||||
2009-07-11T13:45:05.000+0200@null: 10.0kn from 265.0� avg(30000ms): 2009-07-11T13:45:05.000+0200@null: 10.0kn from 269.0�
|
||||
2009-07-12T17:31:40.000+0200@null: 10.0kn from 260.0� avg(30000ms): 2009-07-12T17:31:40.000+0200@null: 10.0kn from 260.0�
|
||||
|
||||
Now assume a query for 2009-07-12T17:30:00 which is closest to the newest entry but (much) more than
|
||||
the averaging interval after the previous entry (2009-07-11T13:45:05.000). This test ensures that
|
||||
the WindTrack uses the newer entry even though it's after the time point requested because it's
|
||||
much closer, and the previous entry would be out of the averaging interval anyway.
|
||||
*/
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-DD-mm'T'hh:mm:ss");
|
||||
Wind wind1 = new WindImpl(null, new MillisecondsTimePoint(df.parse("2009-07-11T13:45:00").getTime()),
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(98)));
|
||||
Wind wind2 = new WindImpl(null, new MillisecondsTimePoint(df.parse("2009-07-11T13:45:05").getTime()),
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(85)));
|
||||
Wind wind3 = new WindImpl(null, new MillisecondsTimePoint(df.parse("2009-07-11T17:31:40").getTime()),
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(80)));
|
||||
WindTrack track = new WindTrackImpl(/* millisecondsOverWhichToAverage */ 30000);
|
||||
track.add(wind1);
|
||||
track.add(wind2);
|
||||
track.add(wind3);
|
||||
TimePoint timePoint = new MillisecondsTimePoint(df.parse("2009-07-11T17:31:38").getTime());
|
||||
Wind result = track.getEstimatedWind(null, timePoint);
|
||||
assertEquals(wind3.getKnots(), result.getKnots(), 0.000000001);
|
||||
assertEquals(wind3.getBearing().getDegrees(), result.getBearing().getDegrees(), 0.0000000001);
|
||||
}
|
||||
}
|
||||
+8
@@ -5,6 +5,8 @@ import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
import com.sap.sailing.domain.tracking.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
@@ -43,4 +45,10 @@ public class TracTracTrackedLegImpl implements TrackedLeg {
|
||||
return trackedRace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpOrDownwindLeg(TimePoint at) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.tracking;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
|
||||
public interface TrackedLeg {
|
||||
Leg getLeg();
|
||||
@@ -12,4 +13,10 @@ public interface TrackedLeg {
|
||||
|
||||
TrackedRace getTrackedRace();
|
||||
|
||||
/**
|
||||
* Determines whether the current {@link #getLeg() leg} is +/- {@link #UPWIND_DOWNWIND_TOLERANCE_IN_DEG} degrees
|
||||
* collinear with the current wind's bearing.
|
||||
*/
|
||||
boolean isUpOrDownwindLeg(TimePoint at) throws NoWindException;
|
||||
|
||||
}
|
||||
+1
-1
@@ -90,5 +90,5 @@ public interface TrackedLegOfCompetitor {
|
||||
* Returns <code>null</code> in case this leg's competitor hasn't started the leg yet.
|
||||
*/
|
||||
Double getEstimatedTimeToNextMarkInSeconds(TimePoint timePoint) throws NoWindException;
|
||||
|
||||
|
||||
}
|
||||
@@ -139,4 +139,6 @@ public interface TrackedRace {
|
||||
TimePoint getTimePointOfNewestEvent();
|
||||
|
||||
NavigableSet<MarkPassing> getMarkPassings(Competitor competitor);
|
||||
|
||||
void removeWind(Wind wind, WindSource windSource);
|
||||
}
|
||||
@@ -2,4 +2,6 @@ package com.sap.sailing.domain.tracking;
|
||||
|
||||
public interface WindListener {
|
||||
void windDataReceived(Wind wind);
|
||||
|
||||
void windDataRemoved(Wind wind);
|
||||
}
|
||||
@@ -24,4 +24,6 @@ public interface WindTrack extends Track<Wind> {
|
||||
* A listener is notified whenever a new fix is added to this track
|
||||
*/
|
||||
void addListener(WindListener listener);
|
||||
|
||||
void remove(Wind wind);
|
||||
}
|
||||
+23
@@ -89,6 +89,17 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersWindRemoved(Wind wind) {
|
||||
for (RaceChangeListener<Competitor> listener : getListeners()) {
|
||||
try {
|
||||
listener.windDataRemoved(wind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListenersWindRemoved(Wind)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners(MarkPassing markPassing) {
|
||||
for (RaceChangeListener<Competitor> listener : getListeners()) {
|
||||
try {
|
||||
@@ -141,6 +152,12 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
getWindTrack(windSource).add(wind);
|
||||
updated(wind.getTimePoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWind(Wind wind, WindSource windSource) {
|
||||
getWindTrack(windSource).remove(wind);
|
||||
updated(wind.getTimePoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gpsFixReceived(GPSFix fix, Competitor competitor) {
|
||||
@@ -158,6 +175,12 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
notifyListeners(wind);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windDataRemoved(Wind wind) {
|
||||
notifyListenersWindRemoved(wind);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TrackedLeg createTrackedLeg(RaceDefinition race, Leg leg) {
|
||||
return new TrackedLegImpl(this, leg, race.getCompetitors());
|
||||
|
||||
+49
@@ -4,11 +4,15 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.sap.sailing.domain.base.Bearing;
|
||||
import com.sap.sailing.domain.base.Buoy;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.Position;
|
||||
import com.sap.sailing.domain.base.TimePoint;
|
||||
import com.sap.sailing.domain.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
@@ -16,6 +20,8 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
public class TrackedLegImpl implements TrackedLeg, RaceChangeListener<Competitor> {
|
||||
private final static double UPWIND_DOWNWIND_TOLERANCE_IN_DEG = 40; // TracTrac does 22.5, Marcus Baur suggest 40
|
||||
|
||||
private final Leg leg;
|
||||
private final Map<Competitor, TrackedLegOfCompetitor> trackedLegsOfCompetitors;
|
||||
private TrackedRaceImpl trackedRace;
|
||||
@@ -82,6 +88,44 @@ public class TrackedLegImpl implements TrackedLeg, RaceChangeListener<Competitor
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpOrDownwindLeg(TimePoint at) throws NoWindException {
|
||||
Wind wind = getWindOnLeg(at);
|
||||
if (wind == null) {
|
||||
throw new NoWindException("Need to know wind direction to determine whether leg "+getLeg()+
|
||||
" is an upwind or downwind leg");
|
||||
}
|
||||
// check for all combinations of start/end waypoint buoys:
|
||||
for (Buoy startBuoy : getLeg().getFrom().getBuoys()) {
|
||||
Position startBuoyPos = getTrackedRace().getTrack(startBuoy).getEstimatedPosition(at, false);
|
||||
for (Buoy endBuoy : getLeg().getTo().getBuoys()) {
|
||||
Position endBuoyPos = getTrackedRace().getTrack(endBuoy).getEstimatedPosition(at, false);
|
||||
Bearing legBearing = startBuoyPos.getBearingGreatCircle(endBuoyPos);
|
||||
double deltaDeg = legBearing.getDegrees() - wind.getBearing().getDegrees();
|
||||
double deltaDegOpposite = legBearing.getDegrees() - wind.getBearing().reverse().getDegrees();
|
||||
if (Math.min(Math.abs(deltaDeg), Math.abs(deltaDegOpposite)) < UPWIND_DOWNWIND_TOLERANCE_IN_DEG) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Wind getWindOnLeg(TimePoint at) {
|
||||
Position approximateLegStartPosition = getTrackedRace().getTrack(
|
||||
getLeg().getFrom().getBuoys().iterator().next()).getEstimatedPosition(at, false);
|
||||
Position approximateLegEndPosition = getTrackedRace().getTrack(
|
||||
getLeg().getTo().getBuoys().iterator().next()).getEstimatedPosition(at, false);
|
||||
Wind wind = getWind(
|
||||
approximateLegStartPosition.translateGreatCircle(approximateLegStartPosition.getBearingGreatCircle(approximateLegEndPosition),
|
||||
approximateLegStartPosition.getDistance(approximateLegEndPosition).scale(0.5)), at);
|
||||
return wind;
|
||||
}
|
||||
|
||||
private Wind getWind(Position p, TimePoint at) {
|
||||
return getTrackedRace().getWind(p, at);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gpsFixReceived(GPSFix fix, Competitor competitor) {
|
||||
clearCaches();
|
||||
@@ -97,6 +141,11 @@ public class TrackedLegImpl implements TrackedLeg, RaceChangeListener<Competitor
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windDataRemoved(Wind wind) {
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
private void clearCaches() {
|
||||
synchronized (competitorTracksOrderedByRank) {
|
||||
competitorTracksOrderedByRank.clear();
|
||||
|
||||
+1
-39
@@ -31,7 +31,6 @@ import com.sap.sailing.domain.tracking.Wind;
|
||||
public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
private final TrackedLegImpl trackedLeg;
|
||||
private final Competitor competitor;
|
||||
private final double UPWIND_DOWNWIND_TOLERANCE_IN_DEG = 40; // TracTrac does 22.5, Marcus Baur suggest 40
|
||||
|
||||
public TrackedLegOfCompetitorImpl(TrackedLegImpl trackedLeg, Competitor competitor) {
|
||||
this.trackedLeg = trackedLeg;
|
||||
@@ -198,7 +197,7 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
* @param at the wind estimation is performed for this point in time
|
||||
*/
|
||||
private Distance getWindwardDistance(Position pos1, Position pos2, TimePoint at) throws NoWindException {
|
||||
if (isUpOrDownwindLeg(at)) {
|
||||
if (getTrackedLeg().isUpOrDownwindLeg(at)) {
|
||||
Wind wind = getWind(pos1.translateGreatCircle(pos1.getBearingGreatCircle(pos2), pos1.getDistance(pos2).scale(0.5)), at);
|
||||
Position projectionToLineThroughPos2 = pos1.projectToLineThrough(pos2, wind.getBearing());
|
||||
return projectionToLineThroughPos2.getDistance(pos2);
|
||||
@@ -236,43 +235,6 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
return getTrackedRace().getWind(p, at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the current {@link #getLeg() leg} is +/- {@link #UPWIND_DOWNWIND_TOLERANCE_IN_DEG} degrees
|
||||
* collinear with the current wind's bearing.
|
||||
*/
|
||||
private boolean isUpOrDownwindLeg(TimePoint at) throws NoWindException {
|
||||
Wind wind = getWindOnLeg(at);
|
||||
if (wind == null) {
|
||||
throw new NoWindException("Need to know wind direction to determine whether leg "+getLeg()+
|
||||
" is an upwind or downwind leg");
|
||||
}
|
||||
// check for all combinations of start/end waypoint buoys:
|
||||
for (Buoy startBuoy : getLeg().getFrom().getBuoys()) {
|
||||
Position startBuoyPos = getTrackedRace().getTrack(startBuoy).getEstimatedPosition(at, false);
|
||||
for (Buoy endBuoy : getLeg().getTo().getBuoys()) {
|
||||
Position endBuoyPos = getTrackedRace().getTrack(endBuoy).getEstimatedPosition(at, false);
|
||||
Bearing legBearing = startBuoyPos.getBearingGreatCircle(endBuoyPos);
|
||||
double deltaDeg = legBearing.getDegrees() - wind.getBearing().getDegrees();
|
||||
double deltaDegOpposite = legBearing.getDegrees() - wind.getBearing().reverse().getDegrees();
|
||||
if (Math.min(Math.abs(deltaDeg), Math.abs(deltaDegOpposite)) < UPWIND_DOWNWIND_TOLERANCE_IN_DEG) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Wind getWindOnLeg(TimePoint at) {
|
||||
Position approximateLegStartPosition = getTrackedRace().getTrack(
|
||||
getLeg().getFrom().getBuoys().iterator().next()).getEstimatedPosition(at, false);
|
||||
Position approximateLegEndPosition = getTrackedRace().getTrack(
|
||||
getLeg().getTo().getBuoys().iterator().next()).getEstimatedPosition(at, false);
|
||||
Wind wind = getWind(
|
||||
approximateLegStartPosition.translateGreatCircle(approximateLegStartPosition.getBearingGreatCircle(approximateLegEndPosition),
|
||||
approximateLegStartPosition.getDistance(approximateLegEndPosition).scale(0.5)), at);
|
||||
return wind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRank(TimePoint timePoint) {
|
||||
TreeSet<TrackedLegOfCompetitor> competitorTracksByRank = getTrackedLeg().getCompetitorTracksOrderedByRank(timePoint);
|
||||
|
||||
+22
-1
@@ -39,12 +39,27 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
|
||||
@Override
|
||||
public synchronized void add(Wind wind) {
|
||||
getInternalFixes().add(wind);
|
||||
notifyListenersAboutReceive(wind);
|
||||
}
|
||||
|
||||
private void notifyListenersAboutReceive(Wind wind) {
|
||||
for (WindListener listener : listeners) {
|
||||
try {
|
||||
listener.windDataReceived(wind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "WindListener "+listener+" threw exception "+t.getMessage());
|
||||
logger.throwing(WindTrackImpl.class.getName(), "add(Wind)", t);
|
||||
logger.throwing(WindTrackImpl.class.getName(), "notifyListenersAboutReceive(Wind)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersAboutRemoval(Wind wind) {
|
||||
for (WindListener listener : listeners) {
|
||||
try {
|
||||
listener.windDataRemoved(wind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "WindListener "+listener+" threw exception "+t.getMessage());
|
||||
logger.throwing(WindTrackImpl.class.getName(), "notifyListenersAboutRemoval(Wind)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,4 +182,10 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
|
||||
public void addListener(WindListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Wind wind) {
|
||||
getInternalFixes().remove(wind);
|
||||
notifyListenersAboutRemoval(wind);
|
||||
}
|
||||
}
|
||||
+6
@@ -237,4 +237,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWind(Wind wind, WindSource windSource) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,4 +32,10 @@ public class MongoWindListener implements com.sap.sailing.domain.tracking.WindLi
|
||||
windTracksCollection.insert(windTrackEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windDataRemoved(Wind wind) {
|
||||
DBObject windTrackEntry = mongoObjectFactory.storeWindTrackEntry(trackedEvent.getEvent(), trackedRace.getRace(), windSource, wind);
|
||||
windTracksCollection.remove(windTrackEntry);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -58,6 +58,8 @@ public class AdminApp extends Servlet {
|
||||
|
||||
private static final String ACTION_NAME_SET_WIND = "setwind";
|
||||
|
||||
private static final String ACTION_NAME_REMOVE_WIND = "removewind";
|
||||
|
||||
private static final String ACTION_NAME_SELECT_WIND_SOURCE = "selectwindsource";
|
||||
|
||||
private static final String ACTION_NAME_SHOW_WIND = "showwind";
|
||||
@@ -106,7 +108,7 @@ public class AdminApp extends Servlet {
|
||||
|
||||
public AdminApp() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
try {
|
||||
@@ -128,6 +130,8 @@ public class AdminApp extends Servlet {
|
||||
listWindTrackers(req, resp);
|
||||
} else if (ACTION_NAME_SET_WIND.equals(action)) {
|
||||
setWind(req, resp);
|
||||
} else if (ACTION_NAME_REMOVE_WIND.equals(action)) {
|
||||
removeWind(req, resp);
|
||||
} else if (ACTION_NAME_SELECT_WIND_SOURCE.equals(action)) {
|
||||
selectWindSource(req, resp);
|
||||
} else if (ACTION_NAME_SHOW_WIND.equals(action)) {
|
||||
@@ -135,7 +139,7 @@ public class AdminApp extends Servlet {
|
||||
} else if (ACTION_NAME_ADD_WIND_TO_MARKS.equals(action)) {
|
||||
addWindToMarks(req, resp);
|
||||
} else {
|
||||
resp.sendError(500, "Unknown action \""+action+"\"");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unknown action \""+action+"\"");
|
||||
}
|
||||
} else {
|
||||
resp.getWriter().println("Hello admin!");
|
||||
@@ -150,11 +154,11 @@ public class AdminApp extends Servlet {
|
||||
InvalidDateException, NoWindException {
|
||||
Event event = getEvent(req);
|
||||
if (event == null) {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
} else {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
TrackedRace trackedRace = getService().getDomainFactory().trackEvent(event).getTrackedRace(race);
|
||||
TimePoint time = getTimePoint(req, PARAM_NAME_TIME, PARAM_NAME_TIME_MILLIS, MillisecondsTimePoint.now());
|
||||
@@ -192,11 +196,11 @@ public class AdminApp extends Servlet {
|
||||
private void showWind(HttpServletRequest req, HttpServletResponse resp) throws IOException, InvalidDateException {
|
||||
Event event = getEvent(req);
|
||||
if (event == null) {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
} else {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
TrackedRace trackedRace = getService().getDomainFactory().trackEvent(event).getTrackedRace(race);
|
||||
TimePoint from = getTimePoint(req, PARAM_NAME_FROM_TIME, PARAM_NAME_FROM_TIME_MILLIS,
|
||||
@@ -241,17 +245,17 @@ public class AdminApp extends Servlet {
|
||||
private void selectWindSource(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
String sourceName = req.getParameter(PARAM_NAME_WINDSOURCE_NAME);
|
||||
if (sourceName == null) {
|
||||
resp.sendError(500, "Wind source name not provided");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Wind source name not provided");
|
||||
} else {
|
||||
try {
|
||||
WindSource windSource = WindSource.valueOf(sourceName);
|
||||
Event event = getEvent(req);
|
||||
if (event == null) {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
} else {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
TrackedRace trackedRace = getService().getDomainFactory().trackEvent(event)
|
||||
.getTrackedRace(race);
|
||||
@@ -273,7 +277,7 @@ public class AdminApp extends Servlet {
|
||||
}
|
||||
errorMessage.append(s.toString());
|
||||
}
|
||||
resp.sendError(500, errorMessage.toString());
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorMessage.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,11 +285,11 @@ public class AdminApp extends Servlet {
|
||||
private void setWind(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
Event event = getEvent(req);
|
||||
if (event == null) {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
} else {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
String bearingAsString = req.getParameter(PARAM_NAME_BEARING);
|
||||
if (bearingAsString != null) {
|
||||
@@ -311,10 +315,50 @@ public class AdminApp extends Servlet {
|
||||
Wind wind = new WindImpl(p, timePoint, speed);
|
||||
getService().getDomainFactory().trackEvent(event).getTrackedRace(race).recordWind(wind, WindSource.WEB);
|
||||
} catch (InvalidDateException e) {
|
||||
resp.sendError(500, "Couldn't parse time specification " + e.getMessage());
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
resp.sendError(500, "wind bearing parameter "+PARAM_NAME_BEARING+" missing");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "wind bearing parameter "+PARAM_NAME_BEARING+" missing");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeWind(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
Event event = getEvent(req);
|
||||
if (event == null) {
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
} else {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
String sourceName = req.getParameter(PARAM_NAME_WINDSOURCE_NAME);
|
||||
if (sourceName == null) {
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Wind source name not provided");
|
||||
} else {
|
||||
WindSource windSource = WindSource.valueOf(sourceName);
|
||||
if (windSource == null) {
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Wind source name " + sourceName + " unknown");
|
||||
} else {
|
||||
try {
|
||||
WindTrack windTrack = getService().getDomainFactory().trackEvent(event)
|
||||
.getTrackedRace(race).getWindTrack(windSource);
|
||||
TimePoint timePoint = getTimePoint(req, PARAM_NAME_TIME, PARAM_NAME_TIME_MILLIS,
|
||||
MillisecondsTimePoint.now());
|
||||
Wind wind = windTrack.getLastFixAtOrBefore(timePoint);
|
||||
if (wind != null && wind.getTimePoint().equals(timePoint)) {
|
||||
windTrack.remove(wind);
|
||||
resp.getWriter().println("Successfully removed entry "+wind);
|
||||
} else {
|
||||
resp.getWriter().println(
|
||||
"No wind recorded for event " + event.getName() + " and race " + race.getName()
|
||||
+ " at " + timePoint.asDate()+". No error, just no effect :-)");
|
||||
}
|
||||
} catch (InvalidDateException e) {
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,11 +379,11 @@ public class AdminApp extends Servlet {
|
||||
private void stopReceivingExpeditionWindForRace(HttpServletRequest req, HttpServletResponse resp) throws SocketException, IOException {
|
||||
Event event = getEvent(req);
|
||||
if (event == null) {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
} else {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
getService().stopTrackingWind(event, race);
|
||||
}
|
||||
@@ -349,15 +393,15 @@ public class AdminApp extends Servlet {
|
||||
private void startReceivingExpeditionWindForRace(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
Event event = getEvent(req);
|
||||
if (event == null) {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
} else {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
String portParam = req.getParameter(PARAM_NAME_PORT);
|
||||
if (portParam == null) {
|
||||
resp.sendError(500, "No port parameter provided");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "No port parameter provided");
|
||||
} else {
|
||||
int port = Integer.valueOf(portParam);
|
||||
String correctByDeclination = req
|
||||
@@ -375,7 +419,7 @@ public class AdminApp extends Servlet {
|
||||
if (event != null) {
|
||||
getService().stopTracking(event);
|
||||
} else {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,12 +459,12 @@ public class AdminApp extends Servlet {
|
||||
if (event != null) {
|
||||
RaceDefinition race = getRaceDefinition(req);
|
||||
if (race == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
getService().stopTracking(event, race);
|
||||
}
|
||||
} else {
|
||||
resp.sendError(500, "Event not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Event not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ public class ModeratorApp extends Servlet {
|
||||
} else if (ACTION_NAME_SHOW_BOAT_POSITIONS.equals(action)) {
|
||||
showBoatPositions(req, resp);
|
||||
} else {
|
||||
resp.sendError(500, "Unknown action \""+action+"\"");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unknown action \""+action+"\"");
|
||||
}
|
||||
} else {
|
||||
resp.getWriter().println("Hello moderator!");
|
||||
@@ -81,7 +81,7 @@ public class ModeratorApp extends Servlet {
|
||||
private void showBoatPositions(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
TrackedRace trackedRace = getTrackedRace(req);
|
||||
if (trackedRace == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
try {
|
||||
TimePoint sinceTimePoint = getTimePoint(req, PARAM_NAME_SINCE, PARAM_NAME_SINCE_MILLIS, null);
|
||||
@@ -119,7 +119,7 @@ public class ModeratorApp extends Servlet {
|
||||
jsonRace.put("competitors", jsonCompetitors);
|
||||
jsonRace.writeJSONString(resp.getWriter());
|
||||
} catch (InvalidDateException e) {
|
||||
resp.sendError(500, "Couldn't parse time specification " + e.getMessage());
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public class ModeratorApp extends Servlet {
|
||||
private void showWaypoints(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||
TrackedRace trackedRace = getTrackedRace(req);
|
||||
if (trackedRace == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
try {
|
||||
TimePoint timePoint = getTimePoint(req, PARAM_NAME_TIME, PARAM_NAME_TIME_MILLIS,
|
||||
@@ -159,7 +159,7 @@ public class ModeratorApp extends Servlet {
|
||||
}
|
||||
jsonWaypoints.writeJSONString(resp.getWriter());
|
||||
} catch (InvalidDateException e) {
|
||||
resp.sendError(500, "Couldn't parse time specification " + e.getMessage());
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,7 +179,7 @@ public class ModeratorApp extends Servlet {
|
||||
Event event = getEvent(req);
|
||||
TrackedRace trackedRace = getTrackedRace(req);
|
||||
if (trackedRace == null) {
|
||||
resp.sendError(500, "Race not found");
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Race not found");
|
||||
} else {
|
||||
try {
|
||||
TimePoint timePoint = getTimePoint(req, PARAM_NAME_TIME, PARAM_NAME_TIME_MILLIS,
|
||||
@@ -220,6 +220,12 @@ public class ModeratorApp extends Servlet {
|
||||
JSONObject jsonLeg = new JSONObject();
|
||||
jsonLeg.put("from", leg.getLeg().getFrom().getName());
|
||||
jsonLeg.put("to", leg.getLeg().getTo().getName());
|
||||
try {
|
||||
jsonLeg.put("upordownwindleg", leg.isUpOrDownwindLeg(timePoint));
|
||||
} catch (NoWindException e) {
|
||||
// no wind, then it's simply no upwind or downwind leg
|
||||
jsonLeg.put("upordownwindleg", "false");
|
||||
}
|
||||
JSONArray jsonCompetitors = new JSONArray();
|
||||
for (Competitor competitor : event.getCompetitors()) {
|
||||
JSONObject jsonCompetitorInLeg = new JSONObject();
|
||||
@@ -304,7 +310,7 @@ public class ModeratorApp extends Servlet {
|
||||
}
|
||||
jsonRace.writeJSONString(resp.getWriter());
|
||||
} catch (InvalidDateException e) {
|
||||
resp.sendError(500, "Couldn't parse time specification " + e.getMessage());
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
|
||||
}
|
||||
}
|
||||
System.out.println("showrace took "+(System.currentTimeMillis()-start)+"ms");
|
||||
|
||||
Reference in new issue
Block a user