mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-14 16:20:57 +00:00
Merge remote-tracking branch 'origin/master' into mark-rounding-inference
Conflicts: java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java
This commit is contained in:
commit
abcc0d2f8c
80 files changed
+992
-269
No files matched your search
@@ -46,6 +46,7 @@ Like businesses, sailors need the latest information to make strategic decisions
|
||||
* [[Project Planning (bigger development)|wiki/planning]]
|
||||
* [[General Event Planning|wiki/general-event-planning]]
|
||||
* [[Information about Extreme Sailing Series|wiki/extreme-sailing-series]]
|
||||
* [[Kieler Woche 2014 event page|wiki/kielerwoche2014]]
|
||||
|
||||
### Internal services (not related to wiki but useful)
|
||||
|
||||
|
||||
+4
@@ -9,7 +9,9 @@ import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.igtimiadapter.datatypes.AntHrm;
|
||||
@@ -19,6 +21,8 @@ import com.sap.sailing.domain.igtimiadapter.datatypes.GpsQualitySatCount;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class FixFactoryTest {
|
||||
@Rule public Timeout AbstractTracTracLiveTestTimeout = new Timeout(2 * 60 * 1000);
|
||||
|
||||
private static final String demoJson = "{\n"+
|
||||
"\"EA-AK-AAAG\": {\n"+
|
||||
"\"1\": {\n"+
|
||||
|
||||
+4
@@ -8,7 +8,9 @@ import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
|
||||
import com.sap.sailing.domain.igtimiadapter.persistence.PersistenceFactory;
|
||||
import com.sap.sailing.mongodb.MongoDBConfiguration;
|
||||
@@ -16,6 +18,8 @@ import com.sap.sailing.mongodb.MongoDBService;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class WebSocketServerListTest {
|
||||
@Rule public Timeout AbstractTracTracLiveTestTimeout = new Timeout(2 * 60 * 1000);
|
||||
|
||||
@Test
|
||||
public void testWebSocketServerList() throws IllegalStateException, ClientProtocolException, IOException, ParseException, URISyntaxException {
|
||||
final ClientImpl testAppClient = new ClientImpl("7fcdd217e0aa16090edb4ad55b09ec43b2021090e209541fc9b7003c2a2b70c6",
|
||||
|
||||
+4
@@ -10,7 +10,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
|
||||
import com.sap.sailing.declination.DeclinationService;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
@@ -29,6 +31,8 @@ import com.sap.sailing.domain.igtimiadapter.shared.IgtimiWindReceiver;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
public class WindReceiverTest {
|
||||
@Rule public Timeout AbstractTracTracLiveTestTimeout = new Timeout(2 * 60 * 1000);
|
||||
|
||||
@Test
|
||||
public void simpleWindReceiverTest() {
|
||||
final List<Wind> windReceived = new ArrayList<>();
|
||||
|
||||
+4
@@ -11,7 +11,9 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sap.sailing.domain.igtimiadapter.Account;
|
||||
@@ -27,6 +29,8 @@ import com.sap.sailing.mongodb.MongoDBService;
|
||||
public class SignInTest {
|
||||
private static final Logger logger = Logger.getLogger(SignInTest.class.getName());
|
||||
|
||||
@Rule public Timeout AbstractTracTracLiveTestTimeout = new Timeout(2 * 60 * 1000);
|
||||
|
||||
@Test
|
||||
public void testSimpleSignIn() throws ClientProtocolException, IOException, IllegalStateException,
|
||||
ParserConfigurationException, SAXException, ClassNotFoundException, InstantiationException,
|
||||
|
||||
+4
@@ -4,6 +4,8 @@ import java.io.IOException;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.Timeout;
|
||||
|
||||
import com.sap.sailing.domain.igtimiadapter.Account;
|
||||
import com.sap.sailing.domain.igtimiadapter.IgtimiConnection;
|
||||
@@ -13,6 +15,8 @@ import com.sap.sailing.domain.igtimiadapter.impl.Activator;
|
||||
public class AbstractTestWithIgtimiConnection {
|
||||
protected IgtimiConnection connection;
|
||||
|
||||
@Rule public Timeout AbstractTracTracLiveTestTimeout = new Timeout(2 * 60 * 1000);
|
||||
|
||||
@Before
|
||||
public void setUp() throws ClientProtocolException, IOException, org.json.simple.parser.ParseException {
|
||||
final IgtimiConnectionFactory connectionFactory = Activator.getInstance().getConnectionFactory();
|
||||
|
||||
+8
-2
@@ -378,8 +378,14 @@ public class IgtimiWindReceiver implements BulkFixReceiver {
|
||||
if (declinationService == null) {
|
||||
trueHeading = hdgm;
|
||||
} else {
|
||||
Declination declination = declinationService.getDeclination(timePoint, position, /* timeoutForOnlineFetchInMilliseconds 5s */ 5000);
|
||||
trueHeading = hdgm.add(declination.getBearingCorrectedTo(timePoint));
|
||||
try {
|
||||
Declination declination = declinationService.getDeclination(timePoint, position, /* timeoutForOnlineFetchInMilliseconds 5s */ 5000);
|
||||
trueHeading = hdgm.add(declination.getBearingCorrectedTo(timePoint));
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Correction of declination was requested but unsuccessful. Can't correct heading "+
|
||||
hdgm+"@"+timePoint+" by declination. Forwarding exception.");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trueHeading = null;
|
||||
|
||||
+5
-1
@@ -154,7 +154,11 @@ public class WebSocketConnectionManager extends WebSocketAdapter implements Live
|
||||
|
||||
private void notifyListeners(List<Fix> fixes) {
|
||||
for (BulkFixReceiver listener : listeners.keySet()) {
|
||||
listener.received(fixes);
|
||||
try {
|
||||
listener.received(fixes);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error notifying listener "+listener+" of Igtimi fixes "+fixes, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -1,8 +1,10 @@
|
||||
package com.sap.sailing.domain.persistence;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
@@ -123,4 +125,6 @@ public interface DomainObjectFactory {
|
||||
DomainFactory getBaseDomainFactory();
|
||||
|
||||
Iterable<Entry<DeviceConfigurationMatcher, DeviceConfiguration>> loadAllDeviceConfigurations();
|
||||
|
||||
Map<String, Set<URL>> loadResultUrls();
|
||||
}
|
||||
+5
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.persistence;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBObject;
|
||||
@@ -131,4 +132,8 @@ public interface MongoObjectFactory {
|
||||
void removeDeviceConfiguration(DeviceConfigurationMatcher matcher);
|
||||
void removeRaceLog(RaceLogIdentifier identifier);
|
||||
|
||||
void storeResultUrl(String resultProviderName, URL url);
|
||||
|
||||
void removeResultUrl(String resultProviderName, URL url);
|
||||
|
||||
}
|
||||
+5
@@ -87,4 +87,9 @@ public enum CollectionNames {
|
||||
* Metadata for the GPSFixes, grouped by Device Identifier.
|
||||
*/
|
||||
GPS_FIXES_METADATA,
|
||||
|
||||
/**
|
||||
* URLs providing race results
|
||||
*/
|
||||
RESULT_URLS,
|
||||
}
|
||||
+23
@@ -1779,4 +1779,27 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
stringRepresentation, deviceType, stringRepresentation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Set<URL>> loadResultUrls() {
|
||||
Map<String, Set<URL>> resultUrls = new HashMap<>();
|
||||
DBCollection resultUrlCollection = database.getCollection(CollectionNames.RESULT_URLS.name());
|
||||
for (DBObject dbObject : resultUrlCollection.find()) {
|
||||
String providerName = (String) dbObject.get(FieldNames.RESULT_PROVIDERNAME.name());
|
||||
String urlString = (String) dbObject.get(FieldNames.RESULT_URL.name());
|
||||
URL url;
|
||||
try {
|
||||
url = new URL(urlString);
|
||||
} catch (MalformedURLException e) {
|
||||
logger.log(Level.SEVERE, "Failed to parse result Url String: " + urlString + ". Did not load url!");
|
||||
continue;
|
||||
}
|
||||
if (!resultUrls.containsKey(providerName)) {
|
||||
resultUrls.put(providerName, new HashSet<URL>());
|
||||
}
|
||||
Set<URL> set = resultUrls.get(providerName);
|
||||
set.add(url);
|
||||
}
|
||||
return resultUrls;
|
||||
}
|
||||
}
|
||||
+3
@@ -108,4 +108,7 @@ public enum FieldNames {
|
||||
|
||||
// Timespan
|
||||
FROM_MILLIS, TO_MILLIS,
|
||||
|
||||
// Result Import url fields
|
||||
RESULT_PROVIDERNAME, RESULT_URL
|
||||
}
|
||||
+17
@@ -1257,4 +1257,21 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
storeRaceLogIdentifier(identifier, query);
|
||||
getRaceLogCollection().remove(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeResultUrl(String resultProviderName, URL url) {
|
||||
DBCollection resultUrlsCollection = database.getCollection(CollectionNames.RESULT_URLS.name());
|
||||
DBObject query = new BasicDBObject(FieldNames.RESULT_PROVIDERNAME.name(), resultProviderName);
|
||||
DBObject entry = new BasicDBObject(FieldNames.RESULT_PROVIDERNAME.name(), resultProviderName);
|
||||
entry.put(FieldNames.RESULT_URL.name(), url.toString());
|
||||
resultUrlsCollection.update(query, entry, /* upsrt */true, /* multi */false, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeResultUrl(String resultProviderName, URL url) {
|
||||
DBCollection resultUrlsCollection = database.getCollection(CollectionNames.RESULT_URLS.name());
|
||||
DBObject query = new BasicDBObjectBuilder().add(FieldNames.RESULT_PROVIDERNAME.name(), resultProviderName)
|
||||
.add(FieldNames.RESULT_URL.name(), url.toString()).get();
|
||||
resultUrlsCollection.remove(query);
|
||||
}
|
||||
}
|
||||
+11
-14
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.domain.racelogtracking.test.impl;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -31,7 +30,7 @@ import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifie
|
||||
import com.sap.sailing.domain.racelogtracking.test.AbstractGPSFixStoreTest;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.impl.BaseRaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRegattaImpl;
|
||||
@@ -39,7 +38,8 @@ import com.sap.sailing.domain.tracking.impl.TrackedRegattaImpl;
|
||||
public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
|
||||
private boolean finishedLoadingFirstBeforeSecond = true;
|
||||
private int numberOfSwitchesBetweenLoadingRaceLogs = 0;
|
||||
private Integer previouslyLoading = null;
|
||||
private int numFixesReceived = 0;
|
||||
|
||||
@Test
|
||||
@@ -114,19 +114,16 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
||||
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline>emptyList(),
|
||||
EmptyWindStore.INSTANCE, store, 0, 0, 0);
|
||||
|
||||
trackedRace.addListener(new BaseRaceChangeListener() {
|
||||
boolean currentlyLoadingFirst = true;
|
||||
trackedRace.addListener(new AbstractRaceChangeListener() {
|
||||
@Override
|
||||
public void competitorPositionChanged(GPSFixMoving fix, Competitor competitor) {
|
||||
numFixesReceived++;
|
||||
if (currentlyLoadingFirst) {
|
||||
if (fix.getTimePoint().asMillis() > numFixes/2) {
|
||||
currentlyLoadingFirst = false;
|
||||
}
|
||||
} else {
|
||||
if (fix.getTimePoint().asMillis() <= numFixes/2) {
|
||||
finishedLoadingFirstBeforeSecond = false;
|
||||
}
|
||||
int currentlyLoading = fix.getTimePoint().asMillis() <= numFixes/2 ? 1 : 2;
|
||||
if (previouslyLoading == null) {
|
||||
previouslyLoading = currentlyLoading;
|
||||
} else if (previouslyLoading != currentlyLoading) {
|
||||
previouslyLoading = currentlyLoading;
|
||||
numberOfSwitchesBetweenLoadingRaceLogs++;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -137,7 +134,7 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
||||
trackedRace.waitForLoadingFromGPSFixStoreToFinishRunning(raceLog);
|
||||
trackedRace.waitForLoadingFromGPSFixStoreToFinishRunning(raceLog2);
|
||||
|
||||
assertTrue(finishedLoadingFirstBeforeSecond);
|
||||
assertEquals(1, numberOfSwitchesBetweenLoadingRaceLogs);
|
||||
assertEquals(numFixes, numFixesReceived);
|
||||
}
|
||||
}
|
||||
+3
@@ -124,6 +124,9 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
|
||||
|
||||
@Override
|
||||
public Nationality getOrCreateNationality(String threeLetterIOCCode) {
|
||||
if (threeLetterIOCCode == null) {
|
||||
threeLetterIOCCode = " ";
|
||||
}
|
||||
synchronized (nationalityCache) {
|
||||
Nationality result = nationalityCache.get(threeLetterIOCCode);
|
||||
if (result == null) {
|
||||
|
||||
+5
-2
@@ -177,15 +177,18 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
|
||||
|
||||
protected void update() {
|
||||
boolean isRecallDisplayed = isRecallDisplayedAnalyzer.analyze();
|
||||
// always call listeners for changed flag, as this does not only affect recal, but also
|
||||
// changes start procedure, for which some text elements need to be updated
|
||||
// ({@link BaseRaceInfoFragmen#renderFlagChangesCountdown}
|
||||
changedListeners.onActiveFlagsChanged(this);
|
||||
|
||||
if (cachedIsIndividualRecallDisplayed != isRecallDisplayed) {
|
||||
cachedIsIndividualRecallDisplayed = isRecallDisplayed;
|
||||
if (cachedIsIndividualRecallDisplayed) {
|
||||
changedListeners.onIndividualRecallDisplayed(this);
|
||||
changedListeners.onActiveFlagsChanged(this);
|
||||
rescheduleIndividualRecallTimeout(recallDisplayedFinder.analyze());
|
||||
} else {
|
||||
changedListeners.onIndividualRecallRemoved(this);
|
||||
changedListeners.onActiveFlagsChanged(this);
|
||||
unscheduleStateEvent(RaceStateEvents.INDIVIDUAL_RECALL_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.Sideline;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.DomainFactoryImpl;
|
||||
import com.sap.sailing.domain.base.impl.DynamicBoat;
|
||||
import com.sap.sailing.domain.base.impl.DynamicTeam;
|
||||
import com.sap.sailing.domain.base.impl.FleetImpl;
|
||||
import com.sap.sailing.domain.base.impl.MarkImpl;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.SeriesImpl;
|
||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||
import com.sap.sailing.domain.common.Color;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
|
||||
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
|
||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
|
||||
public class LeaderboardCourseChangeTest {
|
||||
|
||||
/**
|
||||
* See bug 2011
|
||||
*
|
||||
* @throws NoWindException
|
||||
* @throws InterruptedException
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
@Test
|
||||
public void testLeaderboardDTOCreationForCourseChange() throws NoWindException, InterruptedException, ExecutionException {
|
||||
|
||||
Date date = Calendar.getInstance().getTime();
|
||||
TimePoint timePoint = new MillisecondsTimePoint(date);
|
||||
|
||||
TrackedRegattaRegistry trackedRegattaRegistry = mock(TrackedRegattaRegistry.class);
|
||||
|
||||
Fleet fleet = new FleetImpl("TestFleet");
|
||||
Series series = createSeries(trackedRegattaRegistry, fleet);
|
||||
Set<Series> seriesSet = new HashSet<>();
|
||||
seriesSet.add(series);
|
||||
|
||||
BoatClass boatClass = new BoatClassImpl("TestClass", true);
|
||||
|
||||
String raceColumnName = "TestRace";
|
||||
RaceColumn raceColumn = series.addRaceColumn(raceColumnName, trackedRegattaRegistry);
|
||||
ScoringScheme scoringScheme = new LowPoint();
|
||||
Regatta mockedRegatta = new RegattaImpl("TestRegatta", boatClass, seriesSet, false, scoringScheme,
|
||||
UUID.randomUUID(), mock(CourseArea.class));
|
||||
ControlPoint start = new MarkImpl("Start");
|
||||
ControlPoint m1 = new MarkImpl("M1");
|
||||
ControlPoint m2 = new MarkImpl("M2");
|
||||
ControlPoint finish = new MarkImpl("Finish");
|
||||
Set<Waypoint> waypoints = new HashSet<>();
|
||||
Waypoint startWaypoint = new WaypointImpl(start);
|
||||
waypoints.add(startWaypoint);
|
||||
Waypoint m1Waypoint1 = new WaypointImpl(m1);
|
||||
Waypoint m2Waypoint1 = new WaypointImpl(m2);
|
||||
Waypoint m1Waypoint2 = new WaypointImpl(m1);
|
||||
Waypoint m2Waypoint2 = new WaypointImpl(m2);
|
||||
Waypoint m1Waypoint3 = new WaypointImpl(m1);
|
||||
waypoints.add(m1Waypoint1);
|
||||
waypoints.add(m2Waypoint1);
|
||||
waypoints.add(m1Waypoint2);
|
||||
waypoints.add(m2Waypoint2);
|
||||
waypoints.add(m1Waypoint3);
|
||||
Waypoint finishWaypoint = new WaypointImpl(finish);
|
||||
waypoints.add(finishWaypoint);
|
||||
Course course = new CourseImpl(raceColumnName, waypoints);
|
||||
TrackedRace mockedTrackedRace = createSpyedTrackedRace(mockedRegatta, course, timePoint, boatClass);
|
||||
raceColumn.setTrackedRace(fleet, mockedTrackedRace);
|
||||
Set<String> raceColumnNames = new HashSet<>();
|
||||
raceColumnNames.add(raceColumnName);
|
||||
|
||||
int[] ruleRaw = { 5, 3, 2 };
|
||||
ThresholdBasedResultDiscardingRule rule = new ThresholdBasedResultDiscardingRuleImpl(ruleRaw);
|
||||
Leaderboard leaderboard = new RegattaLeaderboardImpl(mockedRegatta, rule);
|
||||
|
||||
DomainFactory baseDomainFactory = new DomainFactoryImpl();
|
||||
LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(timePoint, raceColumnNames, false,
|
||||
trackedRegattaRegistry, baseDomainFactory);
|
||||
|
||||
assertEquals(6, leaderboardDTO.rows.values().iterator().next().fieldsByRaceColumnName.values().iterator()
|
||||
.next().legDetails.size());
|
||||
|
||||
course.removeWaypoint(2);
|
||||
course.removeWaypoint(3);
|
||||
|
||||
leaderboardDTO = leaderboard.getLeaderboardDTO(timePoint, raceColumnNames, false, trackedRegattaRegistry,
|
||||
baseDomainFactory);
|
||||
assertEquals(4, leaderboardDTO.rows.values().iterator().next().fieldsByRaceColumnName.values().iterator()
|
||||
.next().legDetails.size());
|
||||
|
||||
}
|
||||
|
||||
private TrackedRace createSpyedTrackedRace(Regatta regatta, Course course, TimePoint timePoint, BoatClass boatClass) {
|
||||
TrackedRegatta mockedTrackedRegatta = createMockedTrackedRegatta(regatta);
|
||||
RaceDefinition mockedRace = createMockedRace(course, boatClass);
|
||||
TrackedRace spyedTrackedRace = spy(new DynamicTrackedRaceImpl(mockedTrackedRegatta, mockedRace,
|
||||
new HashSet<Sideline>(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, 5000, 20000, 20000));
|
||||
|
||||
return spyedTrackedRace;
|
||||
}
|
||||
|
||||
private RaceDefinition createMockedRace(Course course, BoatClass boatClass) {
|
||||
RaceDefinition mockedRaceDefinition = mock(RaceDefinition.class);
|
||||
when(mockedRaceDefinition.getCompetitors()).thenReturn(new HashSet<Competitor>());
|
||||
when(mockedRaceDefinition.getCourse()).thenReturn(course);
|
||||
when(mockedRaceDefinition.getBoatClass()).thenReturn(new BoatClassImpl("TestClass", true));
|
||||
when(mockedRaceDefinition.getName()).thenReturn("TestRace");
|
||||
Iterable<Competitor> competitorSet = createCompetitorSet(boatClass);
|
||||
when(mockedRaceDefinition.getCompetitors()).thenReturn(competitorSet);
|
||||
return mockedRaceDefinition;
|
||||
}
|
||||
|
||||
private Iterable<Competitor> createCompetitorSet(BoatClass boatClass) {
|
||||
Set<Competitor> competitors = new HashSet<>();
|
||||
DynamicBoat mockedBoat = mock(DynamicBoat.class);
|
||||
when(mockedBoat.getBoatClass()).thenReturn(boatClass);
|
||||
competitors.add(new CompetitorImpl(UUID.randomUUID(), "TestCompetitor", Color.BLACK, mock(DynamicTeam.class),
|
||||
mockedBoat));
|
||||
return competitors;
|
||||
}
|
||||
|
||||
private TrackedRegatta createMockedTrackedRegatta(Regatta regatta) {
|
||||
TrackedRegatta mockedTrackedRegatta = mock(DynamicTrackedRegatta.class);
|
||||
when(mockedTrackedRegatta.getRegatta()).thenReturn(regatta);
|
||||
return mockedTrackedRegatta;
|
||||
}
|
||||
|
||||
private Series createSeries(TrackedRegattaRegistry trackedRegattaRegistry, Fleet fleet) {
|
||||
Set<Fleet> fleets = new HashSet<>();
|
||||
fleets.add(fleet);
|
||||
|
||||
Series series = new SeriesImpl("TestSeries", false, fleets, new HashSet<String>(), trackedRegattaRegistry);
|
||||
return series;
|
||||
}
|
||||
|
||||
}
|
||||
-1
@@ -80,7 +80,6 @@ public class MultipleClassesInRegattaTest {
|
||||
assertEquals("505", kiwotest2.getRegatta().getBoatClass().getName());
|
||||
assertEquals("49er", kiwotest3.getRegatta().getBoatClass().getName());
|
||||
assertEquals("STG", weym470may112014_2.getRegatta().getBoatClass().getName());
|
||||
assertNotSame(weym470may112014_2.getRegatta(), kiwotest1.getRegatta()); // expecting that each race gets a distinct default regatta
|
||||
assertNotSame(kiwotest1.getRegatta(), kiwotest2.getRegatta());
|
||||
assertNotSame(kiwotest1.getRegatta(), kiwotest3.getRegatta());
|
||||
assertNotSame(kiwotest2.getRegatta(), kiwotest3.getRegatta());
|
||||
|
||||
+3
-2
@@ -372,7 +372,7 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
// This is particularly bad if a persistent regatta was loaded but a default regatta was accidentally created.
|
||||
// Then, there is no way but restart the server to get rid of this stale cache entry here.
|
||||
if (result == null) {
|
||||
result = new RegattaImpl(raceLogStore, race.getName(), boatClass, trackedRegattaRegistry,
|
||||
result = new RegattaImpl(raceLogStore, defaultRegattaNameAndBoatClass.getA(), boatClass, trackedRegattaRegistry,
|
||||
// use the low-point system as the default scoring scheme
|
||||
getBaseDomainFactory().createScoringScheme(ScoringSchemeType.LOW_POINT), race.getId(), null);
|
||||
regattaCache.put(key, result);
|
||||
@@ -389,7 +389,8 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
for (IRaceCompetitor competitor : race.getRaceCompetitors()) {
|
||||
competitorClassList.add(competitor.getCompetitor().getCompetitorClass());
|
||||
}
|
||||
Pair<String, BoatClass> defaultRegattaNameAndBoatClass = new Pair<String, BoatClass>(race.getName(), getDominantBoatClass(competitorClassList));
|
||||
Pair<String, BoatClass> defaultRegattaNameAndBoatClass = new Pair<String, BoatClass>(race.getEvent().getName(),
|
||||
getDominantBoatClass(competitorClassList));
|
||||
return defaultRegattaNameAndBoatClass;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
|
||||
private static final Logger logger = Logger.getLogger(RegattaImpl.class.getName());
|
||||
private static final long serialVersionUID = 6509564189552478869L;
|
||||
private final Set<RaceDefinition> races;
|
||||
private Set<RaceDefinition> races;
|
||||
private final BoatClass boatClass;
|
||||
private transient Set<RegattaListener> regattaListeners;
|
||||
private List<? extends Series> series;
|
||||
@@ -185,6 +185,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
MasterDataImportInformation masterDataImportInformation = ongoingMasterDataImportInformation.get();
|
||||
if (masterDataImportInformation != null) {
|
||||
raceLogStore = masterDataImportInformation.getRaceLogStore();
|
||||
races = new HashSet<RaceDefinition>();
|
||||
} else {
|
||||
raceLogStore = EmptyRaceLogStore.INSTANCE;
|
||||
}
|
||||
|
||||
+28
-31
@@ -1,10 +1,11 @@
|
||||
package com.sap.sailing.domain.leaderboard;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorChangeListener;
|
||||
@@ -29,6 +30,7 @@ import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.util.impl.ConcurrentWeakHashMap;
|
||||
import com.sap.sailing.util.impl.LockUtil;
|
||||
import com.sap.sailing.util.impl.NamedReentrantReadWriteLock;
|
||||
|
||||
@@ -45,7 +47,7 @@ public class LeaderboardCacheManager {
|
||||
private final WeakHashMap<Leaderboard, CacheInvalidationUponScoreCorrectionListener> scoreCorrectionListeners;
|
||||
private final NamedReentrantReadWriteLock scoreCorrectionAndCompetitorChangeListenersLock;
|
||||
private final WeakHashMap<Leaderboard, CacheInvalidationUponCompetitorChangeListener> competitorChangeListeners;
|
||||
private final WeakHashMap<Leaderboard, Map<TrackedRace, Set<CacheInvalidationListener>>> invalidationListenersPerLeaderboard;
|
||||
private final ConcurrentWeakHashMap<Leaderboard, ConcurrentHashMap<TrackedRace, Set<CacheInvalidationListener>>> invalidationListenersPerLeaderboard;
|
||||
private final WeakHashMap<Leaderboard, RaceColumnListener> raceColumnListeners;
|
||||
|
||||
private class CacheInvalidationListener implements RaceChangeListener {
|
||||
@@ -103,6 +105,16 @@ public class LeaderboardCacheManager {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
removeFromCache(leaderboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayToLiveChanged(long delayToLiveInMillis) {
|
||||
removeFromCache(leaderboard);
|
||||
@@ -209,7 +221,7 @@ public class LeaderboardCacheManager {
|
||||
|
||||
public LeaderboardCacheManager(LeaderboardCache leaderboardCache) {
|
||||
this.leaderboardCache = leaderboardCache;
|
||||
this.invalidationListenersPerLeaderboard = new WeakHashMap<>();
|
||||
this.invalidationListenersPerLeaderboard = new ConcurrentWeakHashMap<>();
|
||||
this.raceColumnListeners = new WeakHashMap<Leaderboard, RaceColumnListener>();
|
||||
this.scoreCorrectionListeners = new WeakHashMap<>();
|
||||
this.scoreCorrectionAndCompetitorChangeListenersLock = new NamedReentrantReadWriteLock(
|
||||
@@ -218,11 +230,10 @@ public class LeaderboardCacheManager {
|
||||
}
|
||||
|
||||
private void removeFromCache(Leaderboard leaderboard) {
|
||||
synchronized (invalidationListenersPerLeaderboard) {
|
||||
Map<TrackedRace, Set<CacheInvalidationListener>> listenersMap = invalidationListenersPerLeaderboard
|
||||
.remove(leaderboard);
|
||||
if (listenersMap != null) {
|
||||
for (Map.Entry<TrackedRace, Set<CacheInvalidationListener>> e : listenersMap.entrySet()) {
|
||||
ConcurrentHashMap<TrackedRace, Set<CacheInvalidationListener>> listenersMap = invalidationListenersPerLeaderboard.remove(leaderboard);
|
||||
if (listenersMap != null) {
|
||||
for (Map.Entry<TrackedRace, Set<CacheInvalidationListener>> e : listenersMap.entrySet()) {
|
||||
synchronized (e.getValue()) { // the Set is a Collections.synchronizedSet, and synchronization is required for iteration
|
||||
for (CacheInvalidationListener listener : e.getValue()) {
|
||||
listener.removeFromTrackedRace();
|
||||
}
|
||||
@@ -305,17 +316,7 @@ public class LeaderboardCacheManager {
|
||||
|
||||
@Override
|
||||
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
|
||||
removeFromCache(leaderboard);
|
||||
Map<TrackedRace, Set<CacheInvalidationListener>> listenersMap = invalidationListenersPerLeaderboard
|
||||
.get(leaderboard);
|
||||
if (listenersMap != null) {
|
||||
Set<CacheInvalidationListener> listeners = listenersMap.get(trackedRace);
|
||||
if (listeners != null) {
|
||||
for (CacheInvalidationListener listener : listeners) {
|
||||
listener.removeFromTrackedRace();
|
||||
}
|
||||
}
|
||||
}
|
||||
removeFromCache(leaderboard); // removes all listeners from invalidationListenersPerLeaderboard and from their TrackedRaces
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -393,24 +394,20 @@ public class LeaderboardCacheManager {
|
||||
}
|
||||
|
||||
private void registerListener(final Leaderboard leaderboard, TrackedRace trackedRace) {
|
||||
Map<TrackedRace, Set<CacheInvalidationListener>> invalidationListeners;
|
||||
ConcurrentHashMap<TrackedRace, Set<CacheInvalidationListener>> invalidationListeners;
|
||||
final CacheInvalidationListener listener;
|
||||
synchronized (invalidationListenersPerLeaderboard) {
|
||||
listener = new CacheInvalidationListener(leaderboard, trackedRace);
|
||||
trackedRace.addListener(listener);
|
||||
invalidationListeners = invalidationListenersPerLeaderboard.get(leaderboard);
|
||||
if (invalidationListeners == null) {
|
||||
invalidationListeners = new HashMap<TrackedRace, Set<CacheInvalidationListener>>();
|
||||
invalidationListenersPerLeaderboard.put(leaderboard, invalidationListeners);
|
||||
}
|
||||
listener = new CacheInvalidationListener(leaderboard, trackedRace);
|
||||
trackedRace.addListener(listener);
|
||||
invalidationListeners = invalidationListenersPerLeaderboard.get(leaderboard);
|
||||
if (invalidationListeners == null) {
|
||||
invalidationListeners = new ConcurrentHashMap<TrackedRace, Set<CacheInvalidationListener>>();
|
||||
invalidationListenersPerLeaderboard.put(leaderboard, invalidationListeners);
|
||||
}
|
||||
Set<CacheInvalidationListener> listeners = invalidationListeners.get(trackedRace);
|
||||
if (listeners == null) {
|
||||
listeners = new HashSet<CacheInvalidationListener>();
|
||||
listeners = Collections.synchronizedSet(new HashSet<CacheInvalidationListener>());
|
||||
invalidationListeners.put(trackedRace, listeners);
|
||||
}
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+10
@@ -287,6 +287,16 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
invalidateCacheAndRemoveThisListenerFromTrackedRace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
invalidateCacheAndRemoveThisListenerFromTrackedRace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
invalidateCacheAndRemoveThisListenerFromTrackedRace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statusChanged(TrackedRaceStatus newStatus) {
|
||||
// when the status changes away from LOADING, calculations may start or resume, making it necessary to clear the cache
|
||||
|
||||
+2
-1
@@ -3,13 +3,14 @@ package com.sap.sailing.domain.tracking;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseListener;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
|
||||
|
||||
public interface RaceChangeListener {
|
||||
public interface RaceChangeListener extends CourseListener {
|
||||
void competitorPositionChanged(GPSFixMoving fix, Competitor competitor);
|
||||
|
||||
void markPositionChanged(GPSFix fix, Mark mark);
|
||||
|
||||
@@ -578,8 +578,11 @@ public interface TrackedRace extends Serializable {
|
||||
RaceLog getRaceLog(Serializable identifier);
|
||||
|
||||
/**
|
||||
* a setter for the listener on course design changes. The listener is mostly part of the tracking provider adapter.
|
||||
* @param listener the listener to operate with.
|
||||
* A setter for the listener on course design changes suggested by one of the {@link RaceLog}s attached to this
|
||||
* race. The listener is mostly part of the tracking provider adapter.
|
||||
*
|
||||
* @param listener
|
||||
* the listener to operate with.
|
||||
*/
|
||||
void addCourseDesignChangedListener(CourseDesignChangedListener listener);
|
||||
|
||||
|
||||
+8
@@ -59,5 +59,13 @@ public abstract class AbstractRaceChangeListener implements RaceChangeListener {
|
||||
@Override
|
||||
public void delayToLiveChanged(long delayToLiveInMillis) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
}
|
||||
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
public class BaseRaceChangeListener implements RaceChangeListener {
|
||||
|
||||
@Override
|
||||
public void competitorPositionChanged(GPSFixMoving fix, Competitor competitor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markPositionChanged(GPSFix fix, Mark mark) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markPassingReceived(Competitor competitor, Map<Waypoint, MarkPassing> oldMarkPassings,
|
||||
Iterable<MarkPassing> markPassings) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void speedAveragingChanged(long oldMillisecondsOverWhichToAverage, long newMillisecondsOverWhichToAverage) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windDataReceived(Wind wind, WindSource windSource) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windDataRemoved(Wind wind, WindSource windSource) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windAveragingChanged(long oldMillisecondsOverWhichToAverage, long newMillisecondsOverWhichToAverage) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceTimesChanged(TimePoint startOfTracking, TimePoint endOfTracking, TimePoint startTimeReceived) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayToLiveChanged(long delayToLiveInMillis) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windSourcesToExcludeChanged(Iterable<? extends WindSource> windSourcesToExclude) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statusChanged(TrackedRaceStatus newStatus) {
|
||||
}
|
||||
|
||||
}
|
||||
+35
-1
@@ -85,6 +85,15 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener {
|
||||
|
||||
private static final long serialVersionUID = 4884868659665863604L;
|
||||
|
||||
public void deleteAll() {
|
||||
lockForWrite();
|
||||
try {
|
||||
getInternalRawFixes().clear();
|
||||
} finally {
|
||||
unlockAfterWrite();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteAllLaterThan(TimePoint from) {
|
||||
// TODO use a specialized ArrayList in a specialized ArrayListNavigableSet and then make removeRange public
|
||||
lockForWrite();
|
||||
@@ -171,7 +180,11 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener {
|
||||
FromTimePointToEndUpdateInterval updateInterval) {
|
||||
CrossTrackErrorSumAndNumberOfFixesTrack result;
|
||||
if (oldValue != null) {
|
||||
oldValue.deleteAllLaterThan(updateInterval.getFrom());
|
||||
if (updateInterval == null) {
|
||||
oldValue.deleteAll();
|
||||
} else {
|
||||
oldValue.deleteAllLaterThan(updateInterval.getFrom());
|
||||
}
|
||||
computedCacheUpdate.lockForRead();
|
||||
try {
|
||||
for (CrossTrackErrorSumAndNumberOfFixes entry : computedCacheUpdate.getRawFixes()) {
|
||||
@@ -434,6 +447,27 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates all cache contents for all competitors from the beginning of time
|
||||
*/
|
||||
private void invalidate() {
|
||||
final List<Competitor> shuffledCompetitors = new ArrayList<>(cachePerCompetitor.keySet());
|
||||
Collections.shuffle(shuffledCompetitors);
|
||||
for (Competitor competitor : shuffledCompetitors) {
|
||||
cachePerCompetitor.triggerUpdate(competitor, null /* meaning: from the beginning of time */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CrossTrackErrorCache for competitors "+cachePerCompetitor.keySet();
|
||||
|
||||
+42
@@ -356,6 +356,48 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersWaypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.waypointAdded(zeroBasedIndex, waypointThatGotAdded);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + e.getMessage());
|
||||
logger.log(Level.SEVERE, "notifyListenersWaypointAdded(int, Waypoint)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersWaypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.waypointRemoved(zeroBasedIndex, waypointThatGotRemoved);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + e.getMessage());
|
||||
logger.log(Level.SEVERE, "notifyListenersWaypointRemoved(int, Waypoint)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
super.waypointAdded(zeroBasedIndex, waypointThatGotAdded);
|
||||
notifyListenersWaypointAdded(zeroBasedIndex, waypointThatGotAdded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
super.waypointRemoved(zeroBasedIndex, waypointThatGotRemoved);
|
||||
notifyListenersWaypointRemoved(zeroBasedIndex, waypointThatGotRemoved);
|
||||
}
|
||||
|
||||
private void notifyListeners(GPSFix fix, Mark mark) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
|
||||
+10
@@ -677,6 +677,16 @@ public class TrackBasedEstimationWindTrackImpl extends VirtualWindTrackImpl impl
|
||||
clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markPositionChanged(GPSFix fix, Mark mark) {
|
||||
assert fix != null && fix.getTimePoint() != null;
|
||||
|
||||
+10
@@ -198,6 +198,16 @@ public class TrackedLegImpl implements TrackedLeg, RaceChangeListener {
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
clearCaches(); // necessary because the competitor tracks ordered by rank may change for legs adjacent to the waypoint added
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
clearCaches(); // necessary because the competitor tracks ordered by rank may change for legs adjacent to the waypoint removed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void statusChanged(TrackedRaceStatus newStatus) {
|
||||
// no-op; the leg doesn't mind the tracked race's status being updated
|
||||
|
||||
+1
@@ -2026,6 +2026,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
GPSFixMoving next = approximationPointsIter.next();
|
||||
speedWithBearingOnApproximationFromCurrentToNext = current.getSpeedAndBearingRequiredToReach(next);
|
||||
// compute course change on "approximation track"
|
||||
// FIXME bug 2009: when a maneuver (particularly a penalty circle) is executed at high turn rates, approximations may lead to turns >180deg, hence inferred to turn the wrong way; need to loop across the non-approximated fixes here!
|
||||
CourseChange courseChange = speedWithBearingOnApproximationFromPreviousToCurrent
|
||||
.getCourseChangeRequiredToReach(speedWithBearingOnApproximationFromCurrentToNext);
|
||||
com.sap.sse.common.Util.Pair<GPSFixMoving, CourseChange> courseChangeAtFix = new com.sap.sse.common.Util.Pair<GPSFixMoving, CourseChange>(current,
|
||||
|
||||
@@ -8,7 +8,8 @@ Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Import-Package: com.sap.sailing.resultimport,
|
||||
com.sap.sailing.resultimport.impl,
|
||||
org.osgi.framework;version="1.3.0"
|
||||
org.osgi.framework;version="1.3.0",
|
||||
org.osgi.util.tracker;version="1.5.1"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain,
|
||||
|
||||
+22
-3
@@ -4,9 +4,11 @@ import java.util.logging.Logger;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
import com.sap.sailing.resultimport.impl.ResultUrlRegistryServiceTrackerCustomizer;
|
||||
|
||||
public class Activator implements BundleActivator {
|
||||
private static final Logger logger = Logger.getLogger(Activator.class.getName());
|
||||
@@ -14,6 +16,8 @@ public class Activator implements BundleActivator {
|
||||
private static final String SCAN_DIR_PATH_PROPERTY_NAME = "freg.results";
|
||||
private static final String DEFAULT_SCAN_DIR = "fregresults";
|
||||
|
||||
private ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> resultUrlRegistryServiceTracker;
|
||||
|
||||
/*
|
||||
* For testing, consider using the following URLs:
|
||||
* allUrls.add(new URL("http://www.axel-uhl.de/freg/freg_html_export_sample.html"));
|
||||
@@ -24,11 +28,26 @@ public class Activator implements BundleActivator {
|
||||
if (scanDirPath == null) {
|
||||
scanDirPath = System.getProperty(SCAN_DIR_PATH_PROPERTY_NAME, DEFAULT_SCAN_DIR);
|
||||
}
|
||||
final ScoreCorrectionProviderImpl service = new ScoreCorrectionProviderImpl(ResultUrlRegistry.INSTANCE);
|
||||
bundleContext.registerService(ScoreCorrectionProvider.class, service, /* properties */null);
|
||||
logger.info("Scanning " + scanDirPath + " for official result lists of " + service.getName());
|
||||
logger.info("Scanning " + scanDirPath + " for official result lists of "
|
||||
+ ScoreCorrectionProviderImpl.PROVIDER_NAME);
|
||||
|
||||
resultUrlRegistryServiceTracker = new ServiceTracker<>(bundleContext, ResultUrlRegistry.class,
|
||||
new ResultUrlRegistryServiceTrackerCustomizer(bundleContext) {
|
||||
|
||||
@Override
|
||||
protected ScoreCorrectionProvider configureScoreCorrectionProvider(
|
||||
ResultUrlRegistry resultUrlRegistry) {
|
||||
final ScoreCorrectionProviderImpl service = new ScoreCorrectionProviderImpl(resultUrlRegistry);
|
||||
return service;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
resultUrlRegistryServiceTracker.open();
|
||||
|
||||
}
|
||||
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
resultUrlRegistryServiceTracker.close();
|
||||
}
|
||||
}
|
||||
-2
@@ -6,11 +6,9 @@ import java.util.List;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
import com.google.gwt.uibinder.client.UiField;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.client.place.event.header.EventHeader;
|
||||
import com.sap.sailing.gwt.home.client.place.event.header.EventHeaderResources;
|
||||
import com.sap.sailing.gwt.home.client.place.event.media.EventMedia;
|
||||
import com.sap.sailing.gwt.home.client.place.event.overview.EventOverview;
|
||||
import com.sap.sailing.gwt.home.client.place.event.regattalist.EventRegattaList;
|
||||
|
||||
+3
-2
@@ -223,15 +223,16 @@ public class CompetitorSelectionModel implements CompetitorSelectionProvider {
|
||||
|
||||
@Override
|
||||
public Color getColor(CompetitorDTO competitor) {
|
||||
Color result = null;
|
||||
final Color result;
|
||||
if (allCompetitors.contains(competitor)) {
|
||||
if (competitor.getColor() != null) {
|
||||
result = competitor.getColor();
|
||||
} else {
|
||||
result = competitorsColorMap.getColorByID(competitor);
|
||||
}
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1044,7 +1044,7 @@ public interface StringMessages extends Messages {
|
||||
String eventLogoImageURL();
|
||||
String showPingMarkMappings();
|
||||
String regattaNameMustNotContainSlashes();
|
||||
String showNumberOfRacesCompleted();
|
||||
String racesCompleted();
|
||||
String racesCompletedTooltip();
|
||||
String showNumberOfRacesScored();
|
||||
String racesScored();
|
||||
String racesScoredTooltip();
|
||||
}
|
||||
+3
-3
@@ -1030,6 +1030,6 @@ eventOfficialWebsiteURL=Official Website URL
|
||||
eventLogoImageURL=Logo Image URL
|
||||
showPingMarkMappings=Show Mappings for pinged Marks
|
||||
regattaNameMustNotContainSlashes=Regatta name must not contain slashes
|
||||
showNumberOfRacesCompleted=Show number of races completed
|
||||
racesCompleted=Races completed
|
||||
racesCompletedTooltip=Number of races the competitor has completed in this leaderboard.
|
||||
showNumberOfRacesScored=Number of races scored
|
||||
racesScored=Races scored
|
||||
racesScoredTooltip=Number of races the competitor has completed or gotten a score for in this leaderboard.
|
||||
+3
-3
@@ -1024,6 +1024,6 @@ eventOfficialWebsiteURL=URL der offiziellen Veranstaltungs-Website
|
||||
eventLogoImageURL=URL des Veranstaltungs-Logos
|
||||
showPingMarkMappings=Mappings für gepingte Marks zeigen
|
||||
regattaNameMustNotContainSlashes=Regattaname darf keine Schrägstriche enthalten
|
||||
showNumberOfRacesCompleted=Anzahl vollendeter Rennen
|
||||
racesCompleted=Vollendete Rennen
|
||||
racesCompletedTooltip=Anzahl von Rennen, die der Segler vollendet hat
|
||||
showNumberOfRacesScored=Anzahl bepunkteter Rennen
|
||||
racesScored=Bepunktete Rennen
|
||||
racesScoredTooltip=Anzahl von Rennen, die der Segler vollendet oder für die er Punkte bekommen hat
|
||||
+4
-4
@@ -982,7 +982,7 @@ pleaseSelectAScoringResult=Please select a scoring result...
|
||||
eventOfficialWebsiteURL=Official Website URL
|
||||
eventLogoImageURL=Logo Image URL
|
||||
showPingMarkMappings=Show Mappings for pinged Marks
|
||||
showNumberOfRacesCompleted=Показать количество завершенных гонок
|
||||
racesCompleted=Завершенные гонки
|
||||
racesCompletedTooltip=Количество гонок завершенное участником в данной таблице лидеров
|
||||
regattaNameMustNotContainSlashes=Regatta name must not contain slashes
|
||||
showNumberOfRacesScored=Показать количество завершенных гонок
|
||||
racesScored=Завершенные гонки
|
||||
racesScoredTooltip=Количество гонок завершенное участником в данной таблице лидеров
|
||||
regattaNameMustNotContainSlashes=Regatta name must not contain slashes
|
||||
+1
-1
@@ -1336,7 +1336,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
|
||||
@Override
|
||||
public SafeHtmlHeader getHeader() {
|
||||
return new SafeHtmlHeaderWithTooltip(SafeHtmlUtils.fromString(stringMessages.racesCompleted()), stringMessages.racesCompletedTooltip());
|
||||
return new SafeHtmlHeaderWithTooltip(SafeHtmlUtils.fromString(stringMessages.racesScored()), stringMessages.racesScoredTooltip());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -180,8 +180,8 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
overallDetailCheckboxes);
|
||||
overallDetailDialogContent.add(checkbox);
|
||||
}
|
||||
showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox = dialog.createCheckbox(stringMessages.showNumberOfRacesCompleted());
|
||||
dialog.addTooltip(showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox, stringMessages.showNumberOfRacesCompleted());
|
||||
showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox = dialog.createCheckbox(stringMessages.showNumberOfRacesScored());
|
||||
dialog.addTooltip(showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox, stringMessages.showNumberOfRacesScored());
|
||||
showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox.setValue(showOverallColumnWithNumberOfRacesSailedPerCompetitor);
|
||||
overallDetailDialogContent.add(showOverallColumnWithNumberOfRacesSailedPerCompetitorCheckBox);
|
||||
overallDetailDialog.add(overallDetailDialogContent);
|
||||
|
||||
+45
-10
@@ -5,7 +5,13 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.user.client.Command;
|
||||
import com.google.gwt.user.client.Event;
|
||||
import com.google.gwt.user.client.Event.NativePreviewEvent;
|
||||
import com.google.gwt.user.client.Event.NativePreviewHandler;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.ServiceDefTarget;
|
||||
import com.google.gwt.user.client.ui.DockLayoutPanel;
|
||||
@@ -59,6 +65,8 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
private final MediaServiceAsync mediaService = GWT.create(MediaService.class);
|
||||
private final UserManagementServiceAsync userManagementService = GWT.create(UserManagementService.class);
|
||||
|
||||
private boolean toolbarAndLogoAndTitleBarHidden;
|
||||
|
||||
@Override
|
||||
protected void doOnModuleLoad() {
|
||||
super.doOnModuleLoad();
|
||||
@@ -92,9 +100,10 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
final boolean canReplayWhileLiveIsPossible = GwtHttpRequestUtils.getBooleanParameter(RaceBoardViewConfiguration.PARAM_CAN_REPLAY_DURING_LIVE_RACES, false);
|
||||
final boolean autoSelectMedia = GwtHttpRequestUtils.getBooleanParameter(RaceBoardViewConfiguration.PARAM_AUTOSELECT_MEDIA, false);
|
||||
final boolean showMapControls = GwtHttpRequestUtils.getBooleanParameter(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_MAPCONTROLS, true /* default*/);
|
||||
raceboardViewConfig = new RaceBoardViewConfiguration(activeCompetitorsFilterSetName, showLeaderboard, showWindChart,
|
||||
showCompetitorsChart, canReplayWhileLiveIsPossible, autoSelectMedia);
|
||||
|
||||
final boolean showNavigationPanel = GwtHttpRequestUtils.getBooleanParameter(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_NAVIGATION_PANEL, true /* default */);
|
||||
raceboardViewConfig = new RaceBoardViewConfiguration(activeCompetitorsFilterSetName, showLeaderboard,
|
||||
showWindChart, showCompetitorsChart, canReplayWhileLiveIsPossible, autoSelectMedia, showNavigationPanel);
|
||||
|
||||
final ParallelExecutionCallback<List<String>> getLeaderboardNamesCallback = new ParallelExecutionCallback<List<String>>();
|
||||
final ParallelExecutionCallback<List<RegattaDTO>> getRegattasCallback = new ParallelExecutionCallback<List<RegattaDTO>>();
|
||||
final ParallelExecutionCallback<LeaderboardGroupDTO> getLeaderboardGroupByNameCallback = new ParallelExecutionCallback<LeaderboardGroupDTO>();
|
||||
@@ -165,7 +174,7 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
RaceBoardPanel raceBoardPanel = new RaceBoardPanel(sailingService, mediaService, user, timer, raceSelectionModel, leaderboardName,
|
||||
leaderboardGroupName, raceboardViewConfig, RaceBoardEntryPoint.this, stringMessages, userAgent, raceTimesInfoProvider, showMapControls);
|
||||
raceBoardPanel.fillRegattas(regattas);
|
||||
createRaceBoardInOneScreenMode(raceBoardPanel);
|
||||
createRaceBoardInOneScreenMode(raceBoardPanel, raceboardViewConfig);
|
||||
}
|
||||
|
||||
private RaceDTO findRace(String regattaName, String raceName, List<RegattaDTO> regattas) {
|
||||
@@ -217,21 +226,47 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
return logoAndTitlePanel;
|
||||
}
|
||||
|
||||
private void createRaceBoardInOneScreenMode(RaceBoardPanel raceBoardPanel) {
|
||||
DockLayoutPanel p = new DockLayoutPanel(Unit.PX);
|
||||
private void createRaceBoardInOneScreenMode(RaceBoardPanel raceBoardPanel,
|
||||
RaceBoardViewConfiguration raceboardViewConfiguration) {
|
||||
final DockLayoutPanel p = new DockLayoutPanel(Unit.PX);
|
||||
RootLayoutPanel.get().add(p);
|
||||
Panel toolbarPanel = raceBoardPanel.getToolbarPanel();
|
||||
final Panel toolbarPanel = raceBoardPanel.getToolbarPanel();
|
||||
if (!UserAgentChecker.INSTANCE.isUserAgentSupported(userAgent)) {
|
||||
HTML lbl = new HTML(stringMessages.warningBrowserUnsupported());
|
||||
lbl.setStyleName("browserOptimizedMessage");
|
||||
toolbarPanel.add(lbl);
|
||||
}
|
||||
FlowPanel logoAndTitlePanel = createLogoAndTitlePanel(raceBoardPanel);
|
||||
final FlowPanel logoAndTitlePanel = createLogoAndTitlePanel(raceBoardPanel);
|
||||
FlowPanel timePanel = createTimePanel(raceBoardPanel);
|
||||
p.addNorth(logoAndTitlePanel, 68);
|
||||
p.addNorth(toolbarPanel, 40);
|
||||
p.addSouth(timePanel, 90);
|
||||
toolbarAndLogoAndTitleBarHidden = false;
|
||||
if (!raceboardViewConfiguration.isShowNavigationPanel()) {
|
||||
p.setWidgetHidden(toolbarPanel, true);
|
||||
globalNavigationPanel.setVisible(false);
|
||||
toolbarAndLogoAndTitleBarHidden = true;
|
||||
}
|
||||
Event.addNativePreviewHandler(new NativePreviewHandler() {
|
||||
@Override
|
||||
public void onPreviewNativeEvent(NativePreviewEvent event) {
|
||||
NativeEvent ne = event.getNativeEvent();
|
||||
if ("keydown".equals(ne.getType()) && ne.getCtrlKey()
|
||||
&& (ne.getKeyCode() == 'm' || ne.getKeyCode() == 'M')) {
|
||||
ne.preventDefault();
|
||||
Scheduler.get().scheduleDeferred(new Command() {
|
||||
@Override
|
||||
public void execute() {
|
||||
p.setWidgetHidden(toolbarPanel, !toolbarAndLogoAndTitleBarHidden);
|
||||
globalNavigationPanel.setVisible(toolbarAndLogoAndTitleBarHidden);
|
||||
toolbarAndLogoAndTitleBarHidden = !toolbarAndLogoAndTitleBarHidden;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
p.addSouth(timePanel, 90);
|
||||
p.add(raceBoardPanel);
|
||||
p.addStyleName("dockLayoutPanel");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -163,6 +163,7 @@ public class RaceBoardPanel extends SimplePanel implements RegattasDisplayer, Ra
|
||||
componentControlsPanel = new FlowPanel();
|
||||
componentControlsPanel.addStyleName("raceBoardNavigation");
|
||||
toolbarPanel.add(componentControlsPanel);
|
||||
|
||||
viewControlsPanel = new FlowPanel();
|
||||
viewControlsPanel.addStyleName("raceBoardControls");
|
||||
toolbarPanel.add(viewControlsPanel);
|
||||
|
||||
+10
-2
@@ -12,6 +12,7 @@ public class RaceBoardViewConfiguration {
|
||||
private String activeCompetitorsFilterSetName;
|
||||
private boolean canReplayDuringLiveRaces;
|
||||
private final boolean autoSelectMedia;
|
||||
private final boolean showNavigationPanel;
|
||||
|
||||
public static final String PARAM_VIEW_MODE = "viewMode";
|
||||
public static final String PARAM_VIEW_SHOW_LEADERBOARD = "viewShowLeaderboard";
|
||||
@@ -28,16 +29,19 @@ public class RaceBoardViewConfiguration {
|
||||
showWindChart = false;
|
||||
showCompetitorsChart = false;
|
||||
autoSelectMedia = false;
|
||||
showNavigationPanel = true;
|
||||
}
|
||||
|
||||
public RaceBoardViewConfiguration(String activeCompetitorsFilterSetName, boolean showLeaderboard,
|
||||
boolean showWindChart, boolean showCompetitorsChart, boolean canReplayDuringLiveRaces, boolean autoSelectMedia) {
|
||||
boolean showWindChart, boolean showCompetitorsChart, boolean canReplayDuringLiveRaces,
|
||||
boolean autoSelectMedia, boolean showNavigationPanel) {
|
||||
this.activeCompetitorsFilterSetName = activeCompetitorsFilterSetName;
|
||||
this.showLeaderboard = showLeaderboard;
|
||||
this.showWindChart = showWindChart;
|
||||
this.showCompetitorsChart = showCompetitorsChart;
|
||||
this.canReplayDuringLiveRaces = canReplayDuringLiveRaces;
|
||||
this.autoSelectMedia = autoSelectMedia;
|
||||
this.autoSelectMedia = autoSelectMedia;
|
||||
this.showNavigationPanel = showNavigationPanel;
|
||||
}
|
||||
|
||||
public boolean isShowLeaderboard() {
|
||||
@@ -64,4 +68,8 @@ public class RaceBoardViewConfiguration {
|
||||
return autoSelectMedia;
|
||||
}
|
||||
|
||||
public boolean isShowNavigationPanel() {
|
||||
return showNavigationPanel;
|
||||
}
|
||||
|
||||
}
|
||||
+14
-3
@@ -31,7 +31,7 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
d = -d;
|
||||
}
|
||||
NumberFormat decimalFormat = NumberFormat.getFormat("##.###");
|
||||
return "" + d + '\u00B0' + m + '\u2032' + decimalFormat.format(s) + '\u2033'; // add º, ', " symbols
|
||||
return "" + d + '\u00B0' + m + '\u2032' + decimalFormat.format(s) + '\u2033'; // add �, ', " symbols
|
||||
}
|
||||
|
||||
private static final int MAX_PROCEDURE_FIELDS = 2;
|
||||
@@ -50,7 +50,9 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
private final Label finishTimeLabel = new Label();
|
||||
private final Label finishDurationLabel = new Label();
|
||||
private final Label protestTimeLabel = new Label();
|
||||
private final Label protestDateLabel = new Label();
|
||||
private final Label updateTimeLabel = new Label();
|
||||
private final Label updateDateLabel = new Label();
|
||||
private final Label vesselPositionLabel = new Label();
|
||||
private final Label windLabel = new Label();
|
||||
private final Label startProcedureLabel = new Label();
|
||||
@@ -94,9 +96,9 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
basicsGrid.setWidget(2, 1, protestTimeLabel);
|
||||
basicsGrid.setWidget(0, 2, startDateLabel);
|
||||
basicsGrid.setWidget(1, 2, finishDurationLabel);
|
||||
basicsGrid.setWidget(2, 2, new Label(""));
|
||||
basicsGrid.setWidget(2, 2, protestDateLabel);
|
||||
|
||||
Grid managementGrid = new Grid(3, 2);
|
||||
Grid managementGrid = new Grid(3, 3);
|
||||
managementGrid.setCellSpacing(cellSpacing);
|
||||
managementGrid.setWidget(0, 0, new Label("Last update at"));
|
||||
managementGrid.setWidget(1, 0, new Label("Vessel position"));
|
||||
@@ -104,6 +106,7 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
managementGrid.setWidget(0, 1, updateTimeLabel);
|
||||
managementGrid.setWidget(1, 1, vesselPositionLabel);
|
||||
managementGrid.setWidget(2, 1, windLabel);
|
||||
managementGrid.setWidget(0, 2, updateDateLabel);
|
||||
|
||||
procedureGrid = new FlexTable();
|
||||
procedureGrid.setCellSpacing(cellSpacing);
|
||||
@@ -166,10 +169,18 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
.format(data.raceInfo.protestFinishTime);
|
||||
protestTimeLabel.setText(protestTimeText);
|
||||
|
||||
String protestDateText = data.raceInfo.protestFinishTime == null ? "" : dateFormatter
|
||||
.format(data.raceInfo.protestFinishTime);
|
||||
protestDateLabel.setText(protestDateText);
|
||||
|
||||
String updateTimeText = data.raceInfo.lastUpdateTime == null ? "-" : timeFormatter
|
||||
.format(data.raceInfo.lastUpdateTime);
|
||||
updateTimeLabel.setText(updateTimeText);
|
||||
|
||||
String updateDateText = data.raceInfo.lastUpdateTime == null ? "" : dateFormatter
|
||||
.format(data.raceInfo.lastUpdateTime);
|
||||
updateDateLabel.setText(updateDateText);
|
||||
|
||||
String vesselPositionText = stringMessages.unknown();
|
||||
String windText = stringMessages.unknown();
|
||||
if (data.raceInfo.lastWind != null) {
|
||||
|
||||
+18
-10
@@ -186,27 +186,30 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
flexTable.setWidget(0, 0, eventVenueGrid);
|
||||
flexTable.getCellFormatter().setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
|
||||
boolean showLeaderboardButton = Window.Location.getParameter("enableLeaderboard") != null
|
||||
final boolean showLeaderboardButton = Window.Location.getParameter("enableLeaderboard") != null
|
||||
&& Window.Location.getParameter("enableLeaderboard").equalsIgnoreCase("true");
|
||||
|
||||
if (showLeaderboardButton) {
|
||||
leaderboardCheckBox = addLeaderboardEnablerButton();
|
||||
leaderboardCheckBox.getElement().getStyle().setMarginLeft(20.0, Unit.PX);
|
||||
leaderboardsTabPanel = new TabPanel();
|
||||
leaderboardsTabPanel.setStyleName("RegattaOverview-Leaderboards");
|
||||
mainPanel.add(leaderboardsTabPanel);
|
||||
} else {
|
||||
leaderboardCheckBox = null;
|
||||
leaderboardsTabPanel = null;
|
||||
}
|
||||
|
||||
|
||||
HorizontalPanel refreshStartStopClockPanel = getRefreshStartStopClockPanel();
|
||||
|
||||
flexTable.setWidget(0, 1, refreshStartStopClockPanel);
|
||||
|
||||
mainPanel.add(flexTable);
|
||||
mainPanel.add(regattaRaceStatesComponent);
|
||||
|
||||
if (showLeaderboardButton) {
|
||||
leaderboardsTabPanel = new TabPanel();
|
||||
leaderboardsTabPanel.setStyleName("RegattaOverview-Leaderboards");
|
||||
leaderboardsTabPanel.setVisible(false);
|
||||
mainPanel.add(leaderboardsTabPanel);
|
||||
} else {
|
||||
leaderboardsTabPanel = null;
|
||||
}
|
||||
|
||||
onUpdateUI(uiUpdateTimer.getLiveTimePointAsDate());
|
||||
}
|
||||
|
||||
@@ -254,8 +257,13 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
errorReporter, stringMessages, userAgent, /*showRaceDetails*/false);
|
||||
leaderboardsTabPanel.add(leaderboardPanel, leaderboard.getDisplayName() + " " + stringMessages.leaderboard());
|
||||
}
|
||||
leaderboardsTabPanel.setVisible(true);
|
||||
leaderboardsTabPanel.selectTab(0);
|
||||
if (!result.isEmpty()) {
|
||||
leaderboardsTabPanel.setVisible(true);
|
||||
leaderboardsTabPanel.selectTab(0);
|
||||
} else {
|
||||
leaderboardCheckBox.setValue(false);
|
||||
errorReporter.reportError("Error trying to load leaderboard. Event could not be associated to Regatta.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
|
||||
+17
-10
@@ -16,6 +16,7 @@ import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
|
||||
import com.google.gwt.json.client.JSONObject;
|
||||
import com.google.gwt.json.client.JSONParser;
|
||||
import com.google.gwt.json.client.JSONValue;
|
||||
@@ -38,6 +39,7 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwt.user.datepicker.client.CalendarUtil;
|
||||
import com.google.gwt.view.client.ListDataProvider;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.PassingInstruction;
|
||||
@@ -83,6 +85,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
private ListDataProvider<RegattaOverviewEntryDTO> regattaOverviewDataProvider;
|
||||
private final VerticalPanel mainPanel;
|
||||
private final DateTimeFormat timeFormatter = DateTimeFormat.getFormat("HH:mm:ss");
|
||||
private final DateTimeFormat dateFormatter = DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT);
|
||||
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final StringMessages stringMessages;
|
||||
@@ -207,6 +210,18 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private String formatTime(Date time) {
|
||||
String result = "-";
|
||||
if (time != null) {
|
||||
result = "";
|
||||
if (! CalendarUtil.isSameDate(time, new Date())) {
|
||||
result += dateFormatter.format(time) + " ";
|
||||
}
|
||||
result += timeFormatter.format(time);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private CellTable<RegattaOverviewEntryDTO> createRegattaTable() {
|
||||
CellTable<RegattaOverviewEntryDTO> table = new CellTable<RegattaOverviewEntryDTO>(/* pageSize */10000, tableRes);
|
||||
@@ -341,11 +356,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
TextColumn<RegattaOverviewEntryDTO> raceStartTimeColumn = new TextColumn<RegattaOverviewEntryDTO>() {
|
||||
@Override
|
||||
public String getValue(RegattaOverviewEntryDTO entryDTO) {
|
||||
String result = "-";
|
||||
if (entryDTO.raceInfo.startTime != null) {
|
||||
result = timeFormatter.format(entryDTO.raceInfo.startTime);
|
||||
}
|
||||
return result;
|
||||
return formatTime(entryDTO.raceInfo.startTime);
|
||||
}
|
||||
};
|
||||
raceStartTimeColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||
@@ -459,11 +470,7 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
||||
TextColumn<RegattaOverviewEntryDTO> lastUpdateColumn = new TextColumn<RegattaOverviewEntryDTO>() {
|
||||
@Override
|
||||
public String getValue(RegattaOverviewEntryDTO entryDTO) {
|
||||
String lastUpdateTime = "-";
|
||||
if (entryDTO.raceInfo.lastUpdateTime != null) {
|
||||
lastUpdateTime = timeFormatter.format(entryDTO.raceInfo.lastUpdateTime);
|
||||
}
|
||||
return lastUpdateTime;
|
||||
return formatTime(entryDTO.raceInfo.lastUpdateTime);
|
||||
}
|
||||
};
|
||||
lastUpdateColumn.setSortable(true);
|
||||
|
||||
+26
-6
@@ -396,6 +396,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
|
||||
private final ServiceTracker<ReplicationService, ReplicationService> replicationServiceTracker;
|
||||
|
||||
private final ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> resultUrlRegistryServiceTracker;
|
||||
|
||||
private final ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider> scoreCorrectionProviderServiceTracker;
|
||||
|
||||
private final MongoObjectFactory mongoObjectFactory;
|
||||
@@ -450,6 +452,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
context = Activator.getDefault();
|
||||
racingEventServiceTracker = createAndOpenRacingEventServiceTracker(context);
|
||||
replicationServiceTracker = createAndOpenReplicationServiceTracker(context);
|
||||
resultUrlRegistryServiceTracker = createAndOpenResultUrlRegistryServiceTracker(context);
|
||||
swissTimingAdapterTracker = createAndOpenSwissTimingAdapterTracker(context);
|
||||
tractracAdapterTracker = createAndOpenTracTracAdapterTracker(context);
|
||||
raceLogTrackingAdapterTracker = createAndOpenRaceLogTrackingAdapterTracker(context);
|
||||
@@ -555,6 +558,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> createAndOpenResultUrlRegistryServiceTracker(
|
||||
BundleContext context) {
|
||||
ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> result = new ServiceTracker<ResultUrlRegistry, ResultUrlRegistry>(
|
||||
context, ResultUrlRegistry.class.getName(), null);
|
||||
result.open();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the OSGi system for registered score correction provider services
|
||||
*/
|
||||
@@ -1387,9 +1398,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
public CompactRaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date,
|
||||
Map<String, Date> fromPerCompetitorIdAsString, Map<String, Date> toPerCompetitorIdAsString,
|
||||
boolean extrapolate) throws NoWindException {
|
||||
return new CompactRaceMapDataDTO(getBoatPositions(raceIdentifier, fromPerCompetitorIdAsString,
|
||||
toPerCompetitorIdAsString, extrapolate), getCoursePositions(raceIdentifier, date), getCourseSidelines(raceIdentifier, date), getQuickRanks(
|
||||
raceIdentifier, date));
|
||||
final Map<CompetitorDTO, List<GPSFixDTO>> boatPositions = getBoatPositions(raceIdentifier, fromPerCompetitorIdAsString, toPerCompetitorIdAsString, extrapolate);
|
||||
final CoursePositionsDTO coursePositions = getCoursePositions(raceIdentifier, date);
|
||||
final List<SidelineDTO> courseSidelines = getCourseSidelines(raceIdentifier, date);
|
||||
final List<QuickRankDTO> quickRanks = getQuickRanks(raceIdentifier, date);
|
||||
return new CompactRaceMapDataDTO(boatPositions, coursePositions, courseSidelines, quickRanks);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3387,8 +3400,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
public List<String> getResultImportUrls(String resultProviderName) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
ResultUrlProvider urlBasedScoreCorrectionProvider = getUrlBasedScoreCorrectionProvider(resultProviderName);
|
||||
ResultUrlRegistry resultUrlRegistry = getResultUrlRegistry();
|
||||
if (urlBasedScoreCorrectionProvider != null) {
|
||||
Iterable<URL> allUrls = ResultUrlRegistry.INSTANCE.getResultUrls(resultProviderName);
|
||||
Iterable<URL> allUrls = resultUrlRegistry.getResultUrls(resultProviderName);
|
||||
for (URL url : allUrls) {
|
||||
result.add(url.toString());
|
||||
}
|
||||
@@ -3399,9 +3413,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
@Override
|
||||
public void removeResultImportURLs(String resultProviderName, Set<String> toRemove) throws Exception {
|
||||
ResultUrlProvider urlBasedScoreCorrectionProvider = getUrlBasedScoreCorrectionProvider(resultProviderName);
|
||||
ResultUrlRegistry resultUrlRegistry = getResultUrlRegistry();
|
||||
if (urlBasedScoreCorrectionProvider != null) {
|
||||
for (String urlToRemove : toRemove) {
|
||||
ResultUrlRegistry.INSTANCE.unregisterResultUrl(resultProviderName, new URL(urlToRemove));
|
||||
resultUrlRegistry.unregisterResultUrl(resultProviderName, new URL(urlToRemove));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3410,8 +3425,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
public void addResultImportUrl(String resultProviderName, String url) throws Exception {
|
||||
ResultUrlProvider urlBasedScoreCorrectionProvider = getUrlBasedScoreCorrectionProvider(resultProviderName);
|
||||
if (urlBasedScoreCorrectionProvider != null) {
|
||||
ResultUrlRegistry.INSTANCE.registerResultUrl(resultProviderName, new URL(url));
|
||||
ResultUrlRegistry resultUrlRegistry = getResultUrlRegistry();
|
||||
resultUrlRegistry.registerResultUrl(resultProviderName, new URL(url));
|
||||
}
|
||||
}
|
||||
|
||||
private ResultUrlRegistry getResultUrlRegistry() {
|
||||
return resultUrlRegistryServiceTracker.getService();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-1
@@ -104,11 +104,13 @@ public class LeaderboardGroupPanel extends SimplePanel implements HasWelcomeWidg
|
||||
private final boolean showRaceDetails;
|
||||
private final boolean canReplayDuringLiveRaces;
|
||||
private final boolean showMapControls;
|
||||
private final boolean showNavigationPanel;
|
||||
private final Timer timerForClientServerOffset;
|
||||
|
||||
public LeaderboardGroupPanel(SailingServiceAsync sailingService, StringMessages stringConstants,
|
||||
ErrorReporter errorReporter, final String groupName, String root, String viewMode, boolean embedded,
|
||||
boolean showRaceDetails, boolean canReplayDuringLiveRaces, boolean showMapControls) {
|
||||
boolean showRaceDetails, boolean canReplayDuringLiveRaces, boolean showMapControls,
|
||||
boolean showNavigationPanel) {
|
||||
super();
|
||||
this.isEmbedded = embedded;
|
||||
this.showRaceDetails = showRaceDetails;
|
||||
@@ -117,6 +119,7 @@ public class LeaderboardGroupPanel extends SimplePanel implements HasWelcomeWidg
|
||||
this.sailingService = sailingService;
|
||||
this.stringMessages = stringConstants;
|
||||
this.errorReporter = errorReporter;
|
||||
this.showNavigationPanel = showNavigationPanel;
|
||||
this.root = (root == null || root.length() == 0) ? "leaderboardGroupPanel" : root;
|
||||
this.viewMode = viewMode;
|
||||
setWidth("95%");
|
||||
@@ -424,6 +427,8 @@ public class LeaderboardGroupPanel extends SimplePanel implements HasWelcomeWidg
|
||||
linkParams.put(RaceBoardViewConfiguration.PARAM_CAN_REPLAY_DURING_LIVE_RACES, "true");
|
||||
}
|
||||
linkParams.put(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_MAPCONTROLS, Boolean.toString(showMapControls));
|
||||
linkParams.put(RaceBoardViewConfiguration.PARAM_VIEW_SHOW_NAVIGATION_PANEL,
|
||||
Boolean.toString(showNavigationPanel));
|
||||
linkParams.put("regattaName", raceIdentifier.getRegattaName());
|
||||
linkParams.put("leaderboardGroupName", leaderboardGroup.getName());
|
||||
if (viewMode != null && !viewMode.isEmpty()) {
|
||||
|
||||
+4
-1
@@ -43,6 +43,8 @@ public class SpectatorEntryPoint extends AbstractEntryPoint implements RegattaRe
|
||||
RaceBoardViewConfiguration.PARAM_CAN_REPLAY_DURING_LIVE_RACES, /* defaultValue */ false);
|
||||
final boolean showMapControls = GwtHttpRequestUtils.getBooleanParameter(
|
||||
RaceBoardViewConfiguration.PARAM_VIEW_SHOW_MAPCONTROLS, /* defaultValue */ true);
|
||||
final boolean showNavigationPanel = GwtHttpRequestUtils.getBooleanParameter(
|
||||
RaceBoardViewConfiguration.PARAM_VIEW_SHOW_NAVIGATION_PANEL, true /* default */);
|
||||
boolean showRaceDetails = Window.Location.getParameter("showRaceDetails") != null
|
||||
&& Window.Location.getParameter("showRaceDetails").equalsIgnoreCase("true");
|
||||
final String groupName;
|
||||
@@ -93,7 +95,8 @@ public class SpectatorEntryPoint extends AbstractEntryPoint implements RegattaRe
|
||||
rootPanel.add(groupOverviewPanel);
|
||||
} else {
|
||||
LeaderboardGroupPanel groupPanel = new LeaderboardGroupPanel(sailingService, stringMessages, this,
|
||||
groupName, root, viewModeParamValue, embedded, showRaceDetails, canReplayDuringLiveRaces, showMapControls);
|
||||
groupName, root, viewModeParamValue, embedded, showRaceDetails, canReplayDuringLiveRaces,
|
||||
showMapControls, showNavigationPanel);
|
||||
groupAndFeedbackPanel.add(groupPanel);
|
||||
if (!embedded) {
|
||||
groupPanel.setWelcomeWidget(new SimpleWelcomeWidget(stringMessages.welcomeToSailingAnalytics(),
|
||||
|
||||
+3
-2
@@ -58,8 +58,9 @@ public class TVEntryPoint extends AbstractEntryPoint {
|
||||
RaceBoardViewConfiguration.PARAM_VIEW_SHOW_COMPETITORSCHART, false /* default */);
|
||||
String activeCompetitorsFilterSetName = GwtHttpRequestUtils.getStringParameter(RaceBoardViewConfiguration.PARAM_VIEW_COMPETITOR_FILTER, null /* default*/);
|
||||
final boolean autoSelectMedia = GwtHttpRequestUtils.getBooleanParameter(RaceBoardViewConfiguration.PARAM_AUTOSELECT_MEDIA, false);
|
||||
raceboardViewConfig = new RaceBoardViewConfiguration(activeCompetitorsFilterSetName,
|
||||
showLeaderboard, showWindChart, showCompetitorsChart, /* canReplayWhileLiveIsPossible */ false, autoSelectMedia);
|
||||
raceboardViewConfig = new RaceBoardViewConfiguration(activeCompetitorsFilterSetName, showLeaderboard,
|
||||
showWindChart, showCompetitorsChart, /* canReplayWhileLiveIsPossible */false, autoSelectMedia,
|
||||
showNavigationPanel);
|
||||
|
||||
sailingService.getLeaderboardNames(new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
|
||||
@@ -5,7 +5,15 @@ Bundle-SymbolicName: com.sap.sailing.manage2sail.resultimport.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Import-Package: org.osgi.framework;version="1.5.0"
|
||||
Import-Package: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.leaderboard,
|
||||
com.sap.sailing.domain.persistence,
|
||||
com.sap.sailing.server,
|
||||
com.sap.sailing.server.impl,
|
||||
org.osgi.framework;version="1.5.0"
|
||||
Fragment-Host: com.sap.sailing.manage2sail.resultimport
|
||||
Require-Bundle: org.junit4;bundle-version="4.8.2",
|
||||
com.sap.sse.common
|
||||
com.sap.sse.common,
|
||||
org.mockito.mockito-core;bundle-version="1.9.5",
|
||||
org.objenesis;bundle-version="1.3.0",
|
||||
org.hamcrest;bundle-version="1.1.0"
|
||||
+12
-4
@@ -2,6 +2,7 @@ package com.sap.sailing.manage2sail.resultimport.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -25,11 +26,14 @@ import com.sap.sailing.domain.common.RegattaScoreCorrections;
|
||||
import com.sap.sailing.domain.common.RegattaScoreCorrections.ScoreCorrectionsForRace;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.manage2sail.resultimport.ScoreCorrectionProviderImpl;
|
||||
import com.sap.sailing.resultimport.ResultDocumentDescriptor;
|
||||
import com.sap.sailing.resultimport.ResultDocumentProvider;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
import com.sap.sailing.resultimport.impl.ResultDocumentDescriptorImpl;
|
||||
import com.sap.sailing.resultimport.impl.ResultUrlRegistryImpl;
|
||||
import com.sap.sailing.xrr.resultimport.ParserFactory;
|
||||
import com.sap.sailing.xrr.resultimport.schema.RegattaResults;
|
||||
import com.sap.sse.common.Util;
|
||||
@@ -95,8 +99,10 @@ public class ParserTest {
|
||||
@Test
|
||||
public void testScoreCorrectionProviderFeedingAndHasResults() throws IOException, SAXException,
|
||||
ParserConfigurationException, JAXBException {
|
||||
ScoreCorrectionProviderImpl scoreCorrectionProvider = new ScoreCorrectionProviderImpl(getTestDocumentProvider(),
|
||||
ParserFactory.INSTANCE, ResultUrlRegistry.INSTANCE);
|
||||
ResultUrlRegistry resultUrlRegistry = new ResultUrlRegistryImpl(mock(MongoObjectFactory.class),
|
||||
mock(DomainObjectFactory.class));
|
||||
ScoreCorrectionProviderImpl scoreCorrectionProvider = new ScoreCorrectionProviderImpl(
|
||||
getTestDocumentProvider(), ParserFactory.INSTANCE, resultUrlRegistry);
|
||||
Map<String, Set<com.sap.sse.common.Util.Pair<String, TimePoint>>> hasResultsFor = scoreCorrectionProvider.getHasResultsForBoatClassFromDateByEventName();
|
||||
|
||||
Set<com.sap.sse.common.Util.Pair<String, TimePoint>> resultsForYES = hasResultsFor.get(YES_EVENT_NAME);
|
||||
@@ -107,8 +113,10 @@ public class ParserTest {
|
||||
|
||||
@Test
|
||||
public void testScoreCorrectionProvider() throws Exception {
|
||||
ScoreCorrectionProviderImpl scoreCorrectionProvider = new ScoreCorrectionProviderImpl(getTestDocumentProvider(),
|
||||
ParserFactory.INSTANCE, ResultUrlRegistry.INSTANCE);
|
||||
ResultUrlRegistry resultUrlRegistry = new ResultUrlRegistryImpl(mock(MongoObjectFactory.class),
|
||||
mock(DomainObjectFactory.class));
|
||||
ScoreCorrectionProviderImpl scoreCorrectionProvider = new ScoreCorrectionProviderImpl(
|
||||
getTestDocumentProvider(), ParserFactory.INSTANCE, resultUrlRegistry);
|
||||
Map<String, Set<com.sap.sse.common.Util.Pair<String, TimePoint>>> hasResultsFor = scoreCorrectionProvider.getHasResultsForBoatClassFromDateByEventName();
|
||||
Set<com.sap.sse.common.Util.Pair<String, TimePoint>> resultsForYES = hasResultsFor.get(YES_EVENT_NAME);
|
||||
com.sap.sse.common.Util.Pair<String, TimePoint> resultFor29er = null;
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.sap.sailing.manage2sail.resultimport.test;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
import com.sap.sailing.resultimport.impl.ResultUrlRegistryImpl;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class PersistenceTest {
|
||||
|
||||
@Test
|
||||
public void testResultUrlStoring() throws MalformedURLException {
|
||||
RacingEventService racingEventService = new RacingEventServiceImpl();
|
||||
DomainObjectFactory domainObjectFactory = racingEventService.getDomainObjectFactory();
|
||||
MongoObjectFactory mongoObjectFactory = racingEventService.getMongoObjectFactory();
|
||||
|
||||
ResultUrlRegistry resultUrlRegistry = new ResultUrlRegistryImpl(mongoObjectFactory, domainObjectFactory);
|
||||
|
||||
String testProviderName = "TestProvider";
|
||||
URL testUrl = new URL(
|
||||
"http://manage2sail.com/api/public/links/event/d30883d3-2876-4d7e-af49-891af6cbae1b?accesstoken=bDAv8CwsTM94ujZ&mediaType=json");
|
||||
resultUrlRegistry.registerResultUrl(testProviderName, testUrl);
|
||||
|
||||
Map<String, Set<URL>> resultUrls = domainObjectFactory.loadResultUrls();
|
||||
Assert.assertTrue(resultUrls.containsKey(testProviderName));
|
||||
Set<URL> urls = resultUrls.get(testProviderName);
|
||||
Assert.assertEquals(1, urls.size());
|
||||
URL url = urls.iterator().next();
|
||||
Assert.assertEquals(testUrl, url);
|
||||
|
||||
resultUrlRegistry.unregisterResultUrl(testProviderName, testUrl);
|
||||
|
||||
resultUrls = domainObjectFactory.loadResultUrls();
|
||||
Assert.assertFalse(resultUrls.containsKey(testProviderName));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,8 @@ Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Activator: com.sap.sailing.manage2sail.resultimport.Activator
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Import-Package: org.osgi.framework;version="1.5.0"
|
||||
Import-Package: org.osgi.framework;version="1.5.0",
|
||||
org.osgi.util.tracker;version="1.5.1"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: com.sap.sailing.manage2sail,
|
||||
com.sap.sailing.domain.common,
|
||||
|
||||
+18
-9
@@ -1,6 +1,5 @@
|
||||
package com.sap.sailing.manage2sail.resultimport;
|
||||
|
||||
import java.net.URL;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
@@ -12,26 +11,36 @@ import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
import com.sap.sailing.resultimport.impl.ResultUrlRegistryServiceTrackerCustomizer;
|
||||
import com.sap.sailing.xrr.resultimport.ParserFactory;
|
||||
|
||||
public class Activator implements BundleActivator {
|
||||
// private static String MANAGE2SAIL_KIELWEEK_2013_URL = "http://manage2sail.com/api/public/links/event/da33884e-24fe-44f6-8501-d253587f7cc8?accesstoken=bDAv8CwsTM94ujZ&mediaType=json";
|
||||
private static String MANAGE2SAIL_TW_2013_URL = "http://manage2sail.com/api/public/links/event/937a5c0a-5a28-4a07-806a-8c8ec1efc85c?accesstoken=bDAv8CwsTM94ujZ&mediaType=json";
|
||||
|
||||
private ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> resultUrlRegistryServiceTracker;
|
||||
|
||||
public void start(BundleContext bundleContext) throws Exception {
|
||||
final ScoreCorrectionProviderImpl service = new ScoreCorrectionProviderImpl(ParserFactory.INSTANCE, ResultUrlRegistry.INSTANCE);
|
||||
bundleContext.registerService(ScoreCorrectionProvider.class, service, /* properties */null);
|
||||
|
||||
// ResultUrlRegistry.INSTANCE.registerResultUrl(ScoreCorrectionProviderImpl.NAME, new URL(MANAGE2SAIL_KIELWEEK_2013_URL));
|
||||
ResultUrlRegistry.INSTANCE.registerResultUrl(ScoreCorrectionProviderImpl.NAME, new URL(MANAGE2SAIL_TW_2013_URL));
|
||||
|
||||
resultUrlRegistryServiceTracker = new ServiceTracker<>(bundleContext, ResultUrlRegistry.class,
|
||||
new ResultUrlRegistryServiceTrackerCustomizer(bundleContext) {
|
||||
|
||||
@Override
|
||||
protected ScoreCorrectionProvider configureScoreCorrectionProvider(
|
||||
ResultUrlRegistry resultUrlRegistry) {
|
||||
final ScoreCorrectionProviderImpl service = new ScoreCorrectionProviderImpl(
|
||||
ParserFactory.INSTANCE, resultUrlRegistry);
|
||||
return service;
|
||||
}
|
||||
});
|
||||
|
||||
resultUrlRegistryServiceTracker.open();
|
||||
createAnAllCertificatesTrustingManagerforSSL();
|
||||
}
|
||||
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
resultUrlRegistryServiceTracker.close();
|
||||
}
|
||||
|
||||
private void createAnAllCertificatesTrustingManagerforSSL() throws Exception {
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider, Res
|
||||
if(divisionGender != null) {
|
||||
divisionBoatClassAndGender += ", " + divisionGender.name();
|
||||
}
|
||||
if (boatClassName.equalsIgnoreCase(divisionBoatClassAndGender)) {
|
||||
if (boatClassName.equalsIgnoreCase(divisionBoatClassAndGender) || boatClassName.contains(divisionBoatClassAndGender)) {
|
||||
return new XRRRegattaResultsAsScoreCorrections(event, division, this,
|
||||
parser);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Shared result import APIs
|
||||
Bundle-SymbolicName: com.sap.sailing.resultimport
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Activator: com.sap.sailing.resultimport.Activator
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ActivationPolicy: lazy
|
||||
@@ -11,5 +12,8 @@ Export-Package: com.sap.sailing.resultimport,
|
||||
Import-Package: com.sap.sailing.domain.base.impl,
|
||||
com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.common.impl,
|
||||
org.osgi.framework;version="1.5.0"
|
||||
com.sap.sailing.domain.persistence,
|
||||
com.sap.sailing.server,
|
||||
org.osgi.framework;version="1.5.0",
|
||||
org.osgi.util.tracker;version="1.5.1"
|
||||
Require-Bundle: com.sap.sse.common
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.sap.sailing.resultimport;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
import org.osgi.util.tracker.ServiceTrackerCustomizer;
|
||||
|
||||
import com.sap.sailing.resultimport.impl.ResultUrlRegistryImpl;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class Activator implements BundleActivator {
|
||||
|
||||
private ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
|
||||
|
||||
@Override
|
||||
public void start(BundleContext context) throws Exception {
|
||||
racingEventServiceTracker = new ServiceTracker<RacingEventService, RacingEventService>(context,
|
||||
RacingEventService.class.getName(), new RacingEventServiceTrackerCustomizer(context));
|
||||
racingEventServiceTracker.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
racingEventServiceTracker.close();
|
||||
}
|
||||
|
||||
private class RacingEventServiceTrackerCustomizer implements
|
||||
ServiceTrackerCustomizer<RacingEventService, RacingEventService> {
|
||||
|
||||
private final BundleContext context;
|
||||
|
||||
public RacingEventServiceTrackerCustomizer(BundleContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventService addingService(ServiceReference<RacingEventService> reference) {
|
||||
RacingEventService racingEventService = context.getService(reference);
|
||||
|
||||
ResultUrlRegistry resultUrlRegistryService = new ResultUrlRegistryImpl(
|
||||
racingEventService.getMongoObjectFactory(), racingEventService.getDomainObjectFactory());
|
||||
context.registerService(ResultUrlRegistry.class, resultUrlRegistryService, null);
|
||||
return racingEventService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifiedService(ServiceReference<RacingEventService> reference, RacingEventService service) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removedService(ServiceReference<RacingEventService> reference, RacingEventService service) {
|
||||
}
|
||||
}
|
||||
}
|
||||
-4
@@ -2,15 +2,11 @@ package com.sap.sailing.resultimport;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import com.sap.sailing.resultimport.impl.ResultUrlRegistryImpl;
|
||||
|
||||
/**
|
||||
* A registry for result URL's of score correction providers
|
||||
* @author Frank
|
||||
*/
|
||||
public interface ResultUrlRegistry {
|
||||
ResultUrlRegistry INSTANCE = new ResultUrlRegistryImpl();
|
||||
|
||||
void registerResultUrl(String resultProviderName, URL url);
|
||||
void unregisterResultUrl(String resultProviderName, URL url);
|
||||
|
||||
|
||||
+9
-4
@@ -2,18 +2,21 @@ package com.sap.sailing.resultimport.impl;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
|
||||
public class ResultUrlRegistryImpl implements ResultUrlRegistry {
|
||||
private Map<String, Set<URL>> resultUrls;
|
||||
private final Map<String, Set<URL>> resultUrls;
|
||||
private final MongoObjectFactory mongoObjectFactory;
|
||||
|
||||
public ResultUrlRegistryImpl() {
|
||||
resultUrls = new HashMap<String, Set<URL>>();
|
||||
public ResultUrlRegistryImpl(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory) {
|
||||
this.mongoObjectFactory = mongoObjectFactory;
|
||||
resultUrls = domainObjectFactory.loadResultUrls();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -24,6 +27,7 @@ public class ResultUrlRegistryImpl implements ResultUrlRegistry {
|
||||
resultUrls.put(resultProviderName, urlSet);
|
||||
}
|
||||
urlSet.add(url);
|
||||
mongoObjectFactory.storeResultUrl(resultProviderName, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,6 +35,7 @@ public class ResultUrlRegistryImpl implements ResultUrlRegistry {
|
||||
Set<URL> urlSet = resultUrls.get(resultProviderName);
|
||||
if(urlSet != null) {
|
||||
urlSet.remove(url);
|
||||
mongoObjectFactory.removeResultUrl(resultProviderName, url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.sap.sailing.resultimport.impl;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.util.tracker.ServiceTrackerCustomizer;
|
||||
|
||||
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
|
||||
public abstract class ResultUrlRegistryServiceTrackerCustomizer implements
|
||||
ServiceTrackerCustomizer<ResultUrlRegistry, ResultUrlRegistry> {
|
||||
|
||||
private final BundleContext bundleContext;
|
||||
|
||||
public ResultUrlRegistryServiceTrackerCustomizer(BundleContext bundleContext) {
|
||||
this.bundleContext = bundleContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultUrlRegistry addingService(ServiceReference<ResultUrlRegistry> reference) {
|
||||
ServiceReference<ResultUrlRegistry> serviceRefUrlRegistry = bundleContext
|
||||
.getServiceReference(ResultUrlRegistry.class);
|
||||
ResultUrlRegistry resultUrlRegistry = bundleContext.getService(serviceRefUrlRegistry);
|
||||
|
||||
ScoreCorrectionProvider scoreCorrectionProvider = configureScoreCorrectionProvider(resultUrlRegistry);
|
||||
bundleContext.registerService(ScoreCorrectionProvider.class, scoreCorrectionProvider, /* properties */null);
|
||||
return resultUrlRegistry;
|
||||
}
|
||||
|
||||
protected abstract ScoreCorrectionProvider configureScoreCorrectionProvider(ResultUrlRegistry resultUrlRegistry);
|
||||
|
||||
@Override
|
||||
public void modifiedService(ServiceReference<ResultUrlRegistry> reference, ResultUrlRegistry service) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removedService(ServiceReference<ResultUrlRegistry> reference, ResultUrlRegistry service) {
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -32,7 +32,7 @@ public class TestLeaderboardEditing extends AbstractSeleniumTest {
|
||||
private static final TrackableRaceDescriptor TRACKABLE_RACE = new TrackableRaceDescriptor(
|
||||
BMW_CUP_REGATTA, BMW_CUP_RACE_8, BMW_CUP_BOAT_CLASS);
|
||||
private static final TrackedRaceDescriptor TRACKED_RACE = new TrackedRaceDescriptor(
|
||||
BMW_CUP_RACE_8 + " (" + BMW_CUP_BOAT_CLASS + ")", BMW_CUP_BOAT_CLASS, BMW_CUP_RACE_8);
|
||||
BMW_CUP_REGATTA + " (" + BMW_CUP_BOAT_CLASS + ")", BMW_CUP_BOAT_CLASS, BMW_CUP_RACE_8);
|
||||
private static final RaceDescriptor RACE_COLUMN = new RaceDescriptor("R1", "Default", false, false, 0.0);
|
||||
|
||||
@Before
|
||||
|
||||
+26
-7
@@ -39,6 +39,8 @@ import com.sap.sailing.server.gateway.SailingServerHttpServlet;
|
||||
public class WindStatusServlet extends SailingServerHttpServlet implements IgtimiWindListener, BulkFixReceiver {
|
||||
private static final long serialVersionUID = -6791613843435003810L;
|
||||
|
||||
private final int NUMBER_OF_MESSAGES_TO_SHOW=20;
|
||||
|
||||
private static List<ExpeditionMessageInfo> lastExpeditionMessages;
|
||||
|
||||
private static int igtimiRawMessageCount;
|
||||
@@ -82,14 +84,18 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
out.println("</head>");
|
||||
out.println("<body>");
|
||||
out.println("<h3>Igtimi Wind Status ("+igtimiRawMessageCount+" raw messages received)</h3>");
|
||||
if (lastIgtimiMessages != null && lastIgtimiMessages.size() > 0) {
|
||||
if (lastIgtimiMessages != null && !lastIgtimiMessages.isEmpty()) {
|
||||
final List<IgtimiMessageInfo> copyOfLastIgtimiMessages;
|
||||
synchronized (lastIgtimiMessages) {
|
||||
copyOfLastIgtimiMessages = new ArrayList<>(WindStatusServlet.lastIgtimiMessages);
|
||||
}
|
||||
int counter = 0;
|
||||
for (ListIterator<IgtimiMessageInfo> iterator = WindStatusServlet.lastIgtimiMessages.listIterator(WindStatusServlet.lastIgtimiMessages.size()); iterator.hasPrevious();) {
|
||||
for (ListIterator<IgtimiMessageInfo> iterator = copyOfLastIgtimiMessages.listIterator(copyOfLastIgtimiMessages.size()); iterator.hasPrevious();) {
|
||||
counter++;
|
||||
IgtimiMessageInfo message = iterator.previous();
|
||||
out.println(message);
|
||||
out.println("<br/>");
|
||||
if (counter >= 10) {
|
||||
if (counter >= NUMBER_OF_MESSAGES_TO_SHOW) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -101,9 +107,20 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
}
|
||||
}
|
||||
out.println("<h3>Expedition Wind Status</h3>");
|
||||
if (lastExpeditionMessages.size()>0) {
|
||||
for (ExpeditionMessageInfo message : lastExpeditionMessages) {
|
||||
if (lastExpeditionMessages != null && !lastExpeditionMessages.isEmpty()) {
|
||||
final List<ExpeditionMessageInfo> copyOfLastExpeditionMessages;
|
||||
synchronized (lastExpeditionMessages) {
|
||||
copyOfLastExpeditionMessages = new ArrayList<>(WindStatusServlet.lastExpeditionMessages);
|
||||
}
|
||||
int expeditionMsgCounter = 0;
|
||||
for (ListIterator<ExpeditionMessageInfo> iterator = copyOfLastExpeditionMessages.listIterator(copyOfLastExpeditionMessages.size()); iterator.hasPrevious();) {
|
||||
expeditionMsgCounter++;
|
||||
ExpeditionMessageInfo message = iterator.previous();
|
||||
out.println(message);
|
||||
out.println("<br/>");
|
||||
if (expeditionMsgCounter >= NUMBER_OF_MESSAGES_TO_SHOW) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.println("<i>No Expedition messages received so far!</i>");
|
||||
@@ -146,12 +163,14 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
|
||||
receiver.addListener(new ExpeditionListener() {
|
||||
@Override
|
||||
public void received(ExpeditionMessage message) {
|
||||
if(message != null && message.getBoatID() >= 0) {
|
||||
if (message != null && message.getBoatID() >= 0) {
|
||||
ExpeditionMessageInfo info = new ExpeditionMessageInfo();
|
||||
info.boatID = message.getBoatID();
|
||||
info.message = message;
|
||||
info.messageReceivedAt = new Date();
|
||||
lastExpeditionMessages.add(info);
|
||||
synchronized (lastExpeditionMessages) {
|
||||
lastExpeditionMessages.add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -566,6 +566,7 @@ public class RegattasResource extends AbstractSailingServerResource {
|
||||
JSONObject jsonRaceResults = new JSONObject();
|
||||
jsonRaceResults.put("name", trackedRace.getRace().getName());
|
||||
jsonRaceResults.put("regatta", regatta.getName());
|
||||
jsonRaceResults.put("startOfRace-ms", trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace().asMillis());
|
||||
|
||||
JSONArray jsonLegs = new JSONArray();
|
||||
for (TrackedLeg leg : trackedRace.getTrackedLegs()) {
|
||||
|
||||
+8
-1
@@ -132,7 +132,7 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
|
||||
// anyway. When the tracked race then is loaded it is expected
|
||||
// to automatically be linked to the leaderboard column.
|
||||
master.apply(new ConnectTrackedRaceToLeaderboardColumn(leaderboardName, columnName, defaultFleet.getName(),
|
||||
new RegattaNameAndRaceName("weym470may122011 (STG)", "weym470may122011")));
|
||||
new RegattaNameAndRaceName("Academy Tracking 2011 (STG)", "weym470may122011")));
|
||||
startTracking();
|
||||
assertNotNull(masterColumn.getTrackedRace(defaultFleet)); // ensure the re-assignment worked on the master
|
||||
Thread.sleep(1000);
|
||||
@@ -151,6 +151,13 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
|
||||
@Test
|
||||
public void testRaceTimeReplication() throws InterruptedException, Exception {
|
||||
startTracking();
|
||||
// now wait at least until the start of tracking time has been received on the master copy
|
||||
boolean receivedStartOfTracking = master.getTrackedRace(raceIdentifier).getStartOfTracking() != null;
|
||||
while (!receivedStartOfTracking) { // relying on the Timeout rule for this test
|
||||
Thread.sleep(10);
|
||||
receivedStartOfTracking = master.getTrackedRace(raceIdentifier).getStartOfTracking() != null &&
|
||||
master.getTrackedRace(raceIdentifier).getEndOfTracking() != null;
|
||||
}
|
||||
Thread.sleep(2000); // kept failing several times for a 1000ms timeout
|
||||
TrackedRace replicaTrackedRace = replica.getTrackedRace(raceIdentifier);
|
||||
assertEquals(masterTrackedRace.getStartOfTracking(), replicaTrackedRace.getStartOfTracking());
|
||||
|
||||
+2
@@ -297,6 +297,8 @@ public class MasterDataImportTest {
|
||||
Regatta regattaOnTarget = destService.getRegattaByName(TEST_LEADERBOARD_NAME);
|
||||
Assert.assertNotNull(regattaOnTarget);
|
||||
|
||||
Assert.assertEquals(false, regattaOnTarget.getAllRaces().iterator().hasNext());
|
||||
|
||||
Assert.assertEquals(courseAreaUUID, eventOnTarget.getVenue().getCourseAreas().iterator().next().getId());
|
||||
|
||||
RaceColumn raceColumnOnTarget = leaderboardOnTarget.getRaceColumnByName(raceColumnName);
|
||||
|
||||
+10
@@ -1328,6 +1328,16 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
public void raceTimesChanged(TimePoint startOfTracking, TimePoint endOfTracking, TimePoint startTimeReceived) {
|
||||
replicate(new UpdateRaceTimes(getRaceIdentifier(), startOfTracking, endOfTracking, startTimeReceived));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
|
||||
// no-op; the course change is replicated by the separate CourseChangeReplicator
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
|
||||
// no-op; the course change is replicated by the separate CourseChangeReplicator
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delayToLiveChanged(long delayToLiveInMillis) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
|
||||
public abstract class ExportAction {
|
||||
private HttpServletRequest req;
|
||||
@@ -175,7 +176,8 @@ public abstract class ExportAction {
|
||||
return result;
|
||||
}
|
||||
|
||||
public com.sap.sse.common.Util.Triple<GPSFixMoving, Speed, TrackedLegOfCompetitor> getMaximumSpeedOverGround(Competitor competitor, TrackedRace trackedRace) {
|
||||
public Triple<GPSFixMoving, Speed, TrackedLegOfCompetitor> getMaximumSpeedOverGround(Competitor competitor, TrackedRace trackedRace) {
|
||||
Triple<GPSFixMoving, Speed, TrackedLegOfCompetitor> result = null;
|
||||
com.sap.sse.common.Util.Pair<GPSFixMoving, Speed> speedWithGPSFix = null;
|
||||
TrackedLegOfCompetitor legOfCompetitorWhereSpeedHasBeenReached = null;
|
||||
if (Util.contains(trackedRace.getRace().getCompetitors(), competitor)) {
|
||||
@@ -187,9 +189,10 @@ public abstract class ExportAction {
|
||||
}
|
||||
if (speedWithGPSFix != null) {
|
||||
legOfCompetitorWhereSpeedHasBeenReached = trackedRace.getTrackedLeg(competitor, speedWithGPSFix.getA().getTimePoint());
|
||||
result = new Triple<GPSFixMoving, Speed, TrackedLegOfCompetitor>(speedWithGPSFix.getA(), speedWithGPSFix.getB(), legOfCompetitorWhereSpeedHasBeenReached);
|
||||
}
|
||||
}
|
||||
return new com.sap.sse.common.Util.Triple<GPSFixMoving, Speed, TrackedLegOfCompetitor>(speedWithGPSFix.getA(), speedWithGPSFix.getB(), legOfCompetitorWhereSpeedHasBeenReached);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Speed getAverageSpeedOverGround(Leaderboard leaderboard, Competitor competitor, TimePoint timePoint, boolean alsoIncludeNonFinishedRaces) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Duration;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
@@ -227,8 +228,10 @@ public class LeaderboardData extends ExportAction {
|
||||
|
||||
LineDetails start = race.getStartLine(race.getStartOfTracking());
|
||||
addNamedElementWithValue(raceElement, "start_line_length_in_meters", start.getLength().getMeters());
|
||||
addNamedElementWithValue(raceElement, "start_advantage_in_meters", start.getAdvantage().getMeters());
|
||||
addNamedElementWithValue(raceElement, "advantageous_side_while_approaching_start_line", start.getAdvantageousSideWhileApproachingLine().name());
|
||||
Distance advantage = start.getAdvantage();
|
||||
addNamedElementWithValue(raceElement, "start_advantage_in_meters", advantage != null ? advantage.getMeters() : 0);
|
||||
NauticalSide nauticalSideWhileApproaching = start.getAdvantageousSideWhileApproachingLine();
|
||||
addNamedElementWithValue(raceElement, "advantageous_side_while_approaching_start_line", nauticalSideWhileApproaching != null ? nauticalSideWhileApproaching.name() : "UNKNOWN");
|
||||
|
||||
Distance raceCourseLength = race.getCourseLength();
|
||||
if (raceCourseLength == null) {
|
||||
@@ -435,7 +438,7 @@ public class LeaderboardData extends ExportAction {
|
||||
}
|
||||
addNamedElementWithValue(competitorRaceDataElement, "speed_when_crossing_start_line_in_knots", speedWhenCrossingStartline != null ? speedWhenCrossingStartline.getKnots() : 0);
|
||||
com.sap.sse.common.Util.Triple<GPSFixMoving, Speed, TrackedLegOfCompetitor> gpsFixWithSpeedAndLegInformation = getMaximumSpeedOverGround(competitor, race);
|
||||
if (gpsFixWithSpeedAndLegInformation.getB() != null) {
|
||||
if (gpsFixWithSpeedAndLegInformation != null && gpsFixWithSpeedAndLegInformation.getB() != null) {
|
||||
addNamedElementWithValue(competitorRaceDataElement, "maximum_race_speed_over_ground_in_knots", gpsFixWithSpeedAndLegInformation.getB().getKnots());
|
||||
competitorRaceDataElement.addContent(createTimedXML("maximum_race_speed_measured_at_", gpsFixWithSpeedAndLegInformation.getA().getTimePoint()));
|
||||
if (gpsFixWithSpeedAndLegInformation.getC() != null) {
|
||||
@@ -460,6 +463,8 @@ public class LeaderboardData extends ExportAction {
|
||||
} else {
|
||||
addNamedElementWithValue(competitorRaceDataElement, "maximum_race_speed_over_ground_in_knots", 0.0);
|
||||
competitorRaceDataElement.addContent(createTimedXML("maximum_race_speed_measured_at_", race.getStartOfRace()));
|
||||
addNamedElementWithValue(competitorRaceDataElement, "maximum_race_speed_over_ground_reached_in_leg_with_type", "UNKNOWN");
|
||||
addNamedElementWithValue(competitorRaceDataElement, "maximum_race_speed_over_ground_reached_in_leg", 0);
|
||||
raceConfidenceAndErrorMessages = updateConfidence("Competitor " + competitor.getName() + " has no valid maximum speed for this race!", 0.5, raceConfidenceAndErrorMessages);
|
||||
}
|
||||
Distance distanceTraveledInThisRace = race.getDistanceTraveled(competitor, race.getEndOfRace());
|
||||
|
||||
+11
-7
@@ -1,7 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
# source variables
|
||||
. `pwd`/env.sh
|
||||
if [ "$TMP" = "" ]; then
|
||||
TMP=/tmp
|
||||
fi
|
||||
PWD=`pwd`
|
||||
. "$PWD/env.sh"
|
||||
|
||||
PARAM=$@
|
||||
|
||||
@@ -36,13 +40,13 @@ if [[ $TELNET_ACTIVE != "" ]]; then
|
||||
fi
|
||||
|
||||
scriptdir=`dirname "$0"`
|
||||
LIB_DIR=`pwd`/native-libraries
|
||||
LIB_DIR="$PWD/native-libraries"
|
||||
|
||||
if [[ ! -d `pwd`/logs ]]; then
|
||||
if [[ ! -d "$PWD/logs" ]]; then
|
||||
mkdir logs
|
||||
fi
|
||||
|
||||
if [[ ! -d `pwd`/tmp ]]; then
|
||||
if [[ ! -d "$PWD/tmp" ]]; then
|
||||
mkdir tmp
|
||||
fi
|
||||
|
||||
@@ -72,7 +76,7 @@ APP_PARAMETERS="-Dmongo.host=$MONGODB_HOST -Dmongo.port=$MONGODB_PORT -Dmongo.db
|
||||
REPLICATION_PARAMETERS="-Dreplicate.on.start=$REPLICATE_ON_START -Dreplicate.master.servlet.host=$REPLICATE_MASTER_SERVLET_HOST -Dreplicate.master.servlet.port=$REPLICATE_MASTER_SERVLET_PORT -Dreplicate.master.queue.host=$REPLICATE_MASTER_QUEUE_HOST -Dreplicate.master.queue.port=$REPLICATE_MASTER_QUEUE_PORT"
|
||||
|
||||
if [[ $PARAM == "" ]] || [[ $PARAM == "no-update" ]]; then
|
||||
nohup $JAVA_BINARY -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir=`pwd`/tmp -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Dosgi.shell.telnet.port=$TELNET_PORT -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -configuration ./ -clean 2>/dev/null >/dev/null &
|
||||
nohup $JAVA_BINARY -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir="$PWD/tmp" -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Dosgi.shell.telnet.port=$TELNET_PORT -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -configuration ./ -clean 2>/dev/null >/dev/null &
|
||||
JAVA_PID=$!
|
||||
echo "Starting server... (PID: $JAVA_PID)"
|
||||
echo "SERVER_NAME: $SERVER_NAME"
|
||||
@@ -127,10 +131,10 @@ if [[ $PARAM == "" ]] || [[ $PARAM == "no-update" ]]; then
|
||||
fi
|
||||
elif [[ $PARAM == "debug" ]]; then
|
||||
echo "Starting remote debugging session on port 8000 - make sure this port is open and reachable from the outside"
|
||||
$JAVA_BINARY -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=y -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir=`pwd`/tmp -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -console -configuration ./ -clean
|
||||
$JAVA_BINARY -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=y -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir="$PWD/tmp" -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -console -configuration ./ -clean
|
||||
|
||||
elif [[ $PARAM == "fg" ]]; then
|
||||
$JAVA_BINARY -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir=`pwd`/tmp -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -console -configuration ./ -clean
|
||||
$JAVA_BINARY -D$SERVER_NAME $ADDITIONAL_JAVA_ARGS -Dcom.sap.sailing.server.name=$SERVER_NAME $APP_PARAMETERS $REPLICATION_PARAMETERS -Djava.io.tmpdir="$PWD/tmp" -Dfile.encoding=cp1252 -Djetty.home=$scriptdir/configuration/jetty -Djava.util.logging.config.file=$scriptdir/configuration/logging.properties -Djava.library.path=$LIB_DIR -Xmx$MEMORY -jar plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -console -configuration ./ -clean
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.sap.sailing.racecommittee.app"
|
||||
android:versionCode="4"
|
||||
android:versionName="4.1 - Khalid" >
|
||||
android:versionCode="5"
|
||||
android:versionName="5 - Laser" >
|
||||
|
||||
<uses-sdk
|
||||
android:maxSdkVersion="17"
|
||||
|
||||
File renamed without changes.
+23
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:dslv="http://schemas.android.com/apk**/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="ResAuto" >
|
||||
|
||||
<GridView
|
||||
android:id="@+id/byNameCourseDesignGrid"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:numColumns="10"
|
||||
android:horizontalSpacing="20dp"
|
||||
android:verticalSpacing="20dp"
|
||||
android:columnWidth="40dp"
|
||||
android:padding="10dp"
|
||||
>
|
||||
</GridView>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -9,7 +9,7 @@
|
||||
<item name="android:actionDropDownStyle">@style/MyDropDownNav</item>
|
||||
<item name="android:actionBarStyle">@style/Widget.Welter.ActionBar</item>
|
||||
<item name="android:textColorPrimary">@color/welter_deep_gray</item>
|
||||
|
||||
<item name="android:actionOverflowButtonStyle">@android:style/Widget.Holo.ActionButton.Overflow</item>>
|
||||
<!-- <item name="timePickerStyle">@style/Widget.TimePicker</item> -->
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -163,7 +163,7 @@ public abstract class BaseActivity extends LoggableActivity {
|
||||
sendingServiceStatus = String.format("Currently %d events waiting to be sent.\nLast successful sent was at %s",
|
||||
errorCount, lastSuccessfulSend == null ? "never" : lastSuccessfulSend);
|
||||
} else {
|
||||
menuItemLive.setIcon(R.drawable.ic_menu_share_holo_light);
|
||||
menuItemLive.setIcon(R.drawable.ic_menu_share);
|
||||
sendingServiceStatus = String.format("Currently no event waiting to be sent.", errorCount);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -187,7 +187,6 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
||||
public void onDialogPositiveButton(AttachedDialogFragment dialog) {
|
||||
// We have to take the passed instance, LoginActivity.this might be a new instance!
|
||||
LoginDialog localLoginDialog = (LoginDialog) dialog;
|
||||
preferences.setAuthor(localLoginDialog.getAuthor());
|
||||
switch (localLoginDialog.getSelectedLoginType()) {
|
||||
case OFFICER:
|
||||
ExLog.i(TAG, "Communication with backend is active.");
|
||||
@@ -203,6 +202,7 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
||||
Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
preferences.setAuthor(localLoginDialog.getAuthor());
|
||||
|
||||
if (selectedCourseArea == null) {
|
||||
Toast.makeText(LoginActivity.this, "The selected course area was lost.", Toast.LENGTH_LONG).show();
|
||||
|
||||
+52
-21
@@ -1,18 +1,24 @@
|
||||
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs.coursedesign;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ListAdapter;
|
||||
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.base.impl.CourseDataImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.NaturalComparator;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.RaceDialogFragment;
|
||||
|
||||
@@ -29,36 +35,61 @@ public class ByNameCourseDesignDialog extends RaceDialogFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
TableLayout holder = new TableLayout(getActivity());
|
||||
for (String courseName : preferences.getByNameCourseDesignerCourseNames()) {
|
||||
TableRow rowLayout = new TableRow(getActivity());
|
||||
Button courseButton = new Button(getActivity());
|
||||
courseButton.setText(courseName);
|
||||
courseButton.setOnClickListener( new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onCourseSelectionButtonClicked(v);
|
||||
}
|
||||
});
|
||||
rowLayout.addView(courseButton);
|
||||
holder.addView(rowLayout);
|
||||
}
|
||||
return holder;
|
||||
return inflater.inflate(R.layout.race_choose_by_name_course_design_view, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
getDialog().setTitle(getString(R.string.set_course_layout));
|
||||
|
||||
GridView grid = (GridView) getView().findViewById(R.id.byNameCourseDesignGrid);
|
||||
final List<String> courses = preferences.getByNameCourseDesignerCourseNames();
|
||||
Collections.sort(courses, new NaturalComparator());
|
||||
|
||||
ListAdapter buttonAdapter = new BaseAdapter() {
|
||||
public int getCount() {
|
||||
return courses.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
Button button;
|
||||
if (convertView == null) { // if it's not recycled, initialize some attributes
|
||||
Context ctx = ByNameCourseDesignDialog.this.getView().getContext();
|
||||
button = new Button(ctx);
|
||||
button.setTextSize(ctx.getResources().getDimension(R.dimen.Welter_BigTitleTextSize));
|
||||
button.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onCourseSelectionButtonClicked(v);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
button = (Button) convertView;
|
||||
}
|
||||
|
||||
button.setText(courses.get(position));
|
||||
return button;
|
||||
}
|
||||
};
|
||||
|
||||
grid.setAdapter(buttonAdapter);
|
||||
}
|
||||
|
||||
|
||||
protected void onCourseSelectionButtonClicked(View v) {
|
||||
Button selectedButton = (Button) v;
|
||||
String internalCourseName = (String) selectedButton.getText();
|
||||
|
||||
|
||||
CourseBase courseLayout = new CourseDataImpl(internalCourseName);
|
||||
|
||||
|
||||
getRaceState().setCourseDesign(MillisecondsTimePoint.now(), courseLayout);
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@@ -186,13 +186,15 @@ dir-etc mongodb-databases mysql-databases
|
||||
- Let's assume that you want to recover some score corrections from the archive server. We need to have a look at mongodb-databases and check what is contained there. Keep in mind that wind information is only updated once a week so that not every named backup will contain wind information.
|
||||
|
||||
<pre>
|
||||
[backup@ip-172-31-25-136 database]$ /opt/bup/bup -d /home/backup/database/ ls mongodb-databases
|
||||
2014-05-27-170544 latest
|
||||
[backup@ip-172-31-25-136 database]$ /opt/bup/bup -d /home/backup/database/ ls mongodb-databases/latest
|
||||
[backup@ip-172-31-25-136 restored-files]$ /opt/bup/bup -d /home/backup/database/ ls databases/
|
||||
2014-05-27-212037 2014-05-29-233001 2014-06-01-233001 2014-06-04-203001 2014-06-06-233001 2014-06-09-233001 2014-06-11-233001 2014-06-14-233002 2014-06-17-233001 2014-06-19-233001
|
||||
2014-05-28-203001 2014-05-30-233001 2014-06-02-233001 2014-06-04-233001 2014-06-07-233001 2014-06-10-233001 2014-06-12-233001 2014-06-15-233002 2014-06-18-203001 latest
|
||||
2014-05-28-233001 2014-05-31-233001 2014-06-03-233001 2014-06-05-233001 2014-06-08-233001 2014-06-11-203001 2014-06-13-233001 2014-06-16-233001 2014-06-18-233001
|
||||
[backup@ip-172-31-25-136 database]$ /opt/bup/bup -d /home/backup/database/ ls databases/latest
|
||||
var
|
||||
[backup@ip-172-31-25-136 database]$ /opt/bup/bup -d /home/backup/database/ ls mongodb-databases/latest/var/lib/mysql/backup
|
||||
[backup@ip-172-31-25-136 database]$ /opt/bup/bup -d /home/backup/database/ ls databases/latest/var/lib/mysql/backup
|
||||
mongodb-10201 mongodb-10201-wind mongodb-10202 mongodb-10202-wind mysql
|
||||
[backup@ip-172-31-25-136 database]$ /opt/bup/bup -d /home/backup/database/ ls mongodb-databases/latest/var/lib/mysql/backup/mongodb-10202
|
||||
[backup@ip-172-31-25-136 database]$ /opt/bup/bup -d /home/backup/database/ ls databases/latest/var/lib/mysql/backup/mongodb-10202
|
||||
COMMAND_MESSAGES.json CONFIGURATIONS.json LAST_MESSAGE_COUNT.json LEADERBOARD_GROUPS.json RACE_LOGS.json REGATTA_FOR_RACE_ID.json VIDEOS.json
|
||||
COMPETITORS.json EVENTS.json LEADERBOARDS.json RACES_MESSAGES.json REGATTAS.json TRACTRAC_CONFIGURATIONS.json
|
||||
</pre>
|
||||
|
||||
Reference in new issue
Block a user