Merge branch 'racecommittee_integrated' of ssh://10.18.22.156:12349/home/trac/git into racecommittee_integrated

This commit is contained in:
Lukas Niemeier committed 2013-04-26 19:19:58 +02:00
commit 89e7bf63f3
20 files changed
+318 -110

No files matched your search

@@ -1,6 +1,5 @@
package com.sap.sailing.domain.base.racegroup;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.Named;
import com.sap.sailing.domain.racelog.RaceLog;
@@ -13,6 +12,4 @@ import com.sap.sailing.domain.racelog.RaceLog;
*/
public interface RaceCell extends Named {
RaceLog getRaceLog();
Iterable<Competitor> getCompetitors();
}
@@ -1,6 +1,5 @@
package com.sap.sailing.domain.base.racegroup.impl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.racegroup.RaceCell;
import com.sap.sailing.domain.common.impl.NamedImpl;
import com.sap.sailing.domain.racelog.RaceLog;
@@ -9,12 +8,10 @@ public class RaceCellImpl extends NamedImpl implements RaceCell {
private static final long serialVersionUID = 971598420407273594L;
private RaceLog raceLog;
private Iterable<Competitor> competitors;
public RaceCellImpl(String name, RaceLog raceLog, Iterable<Competitor> competitors) {
public RaceCellImpl(String name, RaceLog raceLog) {
super(name);
this.raceLog = raceLog;
this.competitors = competitors;
}
@Override
@@ -22,9 +19,4 @@ public class RaceCellImpl extends NamedImpl implements RaceCell {
return raceLog;
}
@Override
public Iterable<Competitor> getCompetitors() {
return competitors;
}
}
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.base.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -43,8 +44,16 @@ public class CourseImpl extends NamedImpl implements Course {
private transient Set<CourseListener> listeners;
private transient NamedReentrantReadWriteLock lock;
/**
* This monitor is used to serialize calls to {@link #update(List, DomainFactory)}. This helps to guarantee that
* the transition from a read lock to a write lock, in case a write is actually needed, isn't interrupted by any other
* call to {@link #update(List, DomainFactory)}.
*/
private final Serializable updateMonitor;
public CourseImpl(String name, Iterable<Waypoint> waypoints) {
super(name);
updateMonitor = "";
lock = new NamedReentrantReadWriteLock("lock for CourseImpl "+name,
/* fair */ true); // if non-fair, course update may need to wait forever for many concurrent readers
listeners = new HashSet<CourseListener>();
@@ -320,7 +329,7 @@ public class CourseImpl extends NamedImpl implements Course {
}
@Override
public synchronized Waypoint getWaypointForControlPoint(ControlPoint controlPoint, int start) {
public Waypoint getWaypointForControlPoint(ControlPoint controlPoint, int start) {
lockForRead();
try {
if (start > legs.size()) {
@@ -372,44 +381,51 @@ public class CourseImpl extends NamedImpl implements Course {
@Override
public void update(List<Pair<ControlPoint, NauticalSide>> newControlPoints, DomainFactory baseDomainFactory) throws PatchFailedException {
LockUtil.lockForWrite(lock);
try {
Iterable<Waypoint> courseWaypoints = getWaypoints();
List<Waypoint> newWaypointList = new LinkedList<Waypoint>();
// key existing waypoints by control points and re-use each one at most once during construction of the
// new waypoint list; since several waypoints can have the same control point, the map goes from
// control point to List<Waypoint>. The waypoints in the lists are held in the order of their
// occurrence in courseToUpdate.getWaypoints().
Map<com.sap.sailing.domain.base.ControlPoint, List<Waypoint>> existingWaypointsByControlPoint =
new HashMap<com.sap.sailing.domain.base.ControlPoint, List<Waypoint>>();
for (Waypoint waypoint : courseWaypoints) {
List<Waypoint> wpl = existingWaypointsByControlPoint.get(waypoint.getControlPoint());
if (wpl == null) {
wpl = new ArrayList<Waypoint>();
existingWaypointsByControlPoint.put(waypoint.getControlPoint(), wpl);
Patch<Waypoint> patch = null;
synchronized (updateMonitor) {
lockForRead();
try {
Iterable<Waypoint> courseWaypoints = getWaypoints();
List<Waypoint> newWaypointList = new LinkedList<Waypoint>();
// key existing waypoints by control points and re-use each one at most once during construction of the
// new waypoint list; since several waypoints can have the same control point, the map goes from
// control point to List<Waypoint>. The waypoints in the lists are held in the order of their
// occurrence in courseToUpdate.getWaypoints().
Map<com.sap.sailing.domain.base.ControlPoint, List<Waypoint>> existingWaypointsByControlPoint = new HashMap<com.sap.sailing.domain.base.ControlPoint, List<Waypoint>>();
for (Waypoint waypoint : courseWaypoints) {
List<Waypoint> wpl = existingWaypointsByControlPoint.get(waypoint.getControlPoint());
if (wpl == null) {
wpl = new ArrayList<Waypoint>();
existingWaypointsByControlPoint.put(waypoint.getControlPoint(), wpl);
}
wpl.add(waypoint);
}
wpl.add(waypoint);
}
for (Pair<ControlPoint, NauticalSide> newDomainControlPoint : newControlPoints) {
List<Waypoint> waypoints = existingWaypointsByControlPoint.get(newDomainControlPoint.getA());
Waypoint waypoint;
if (waypoints == null || waypoints.isEmpty()) {
// must be a new control point for which we don't have a waypoint yet
waypoint = baseDomainFactory.createWaypoint(newDomainControlPoint.getA(), newDomainControlPoint.getB());
} else {
waypoint = waypoints.remove(0); // take the first from the list
for (Pair<ControlPoint, NauticalSide> newDomainControlPoint : newControlPoints) {
List<Waypoint> waypoints = existingWaypointsByControlPoint.get(newDomainControlPoint.getA());
Waypoint waypoint;
if (waypoints == null || waypoints.isEmpty()) {
// must be a new control point for which we don't have a waypoint yet
waypoint = baseDomainFactory.createWaypoint(newDomainControlPoint.getA(),
newDomainControlPoint.getB());
} else {
waypoint = waypoints.remove(0); // take the first from the list
}
newWaypointList.add(waypoint);
}
newWaypointList.add(waypoint);
patch = DiffUtils.diff(courseWaypoints, newWaypointList);
} finally {
unlockAfterRead();
}
Patch<Waypoint> patch = DiffUtils.diff(courseWaypoints, newWaypointList);
if (!patch.isEmpty()) {
logger.info("applying course update " + patch + " to course " + this);
CourseAsWaypointList courseAsWaypointList = new CourseAsWaypointList(this);
patch.applyToInPlace(courseAsWaypointList);
if (patch != null && !patch.isEmpty()) {
lockForWrite();
try {
logger.info("applying course update " + patch + " to course " + this);
CourseAsWaypointList courseAsWaypointList = new CourseAsWaypointList(this);
patch.applyToInPlace(courseAsWaypointList);
} finally {
unlockAfterWrite();
}
}
} finally {
LockUtil.unlockAfterWrite(lock);
}
}
}
@@ -871,7 +871,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
LegEntryDTO legEntry;
// We loop over a copy of the course's legs; during a course change, legs may become "stale," even with
// regard to the leg/trackedLeg structures inside the tracked race which is updated by the course change
// immediately. Make sure we're tolerant against disappearing legs! See bug 794.
// immediately. That's why we've acquired a read lock for the course above.
TrackedLegOfCompetitor trackedLeg = trackedRace.getTrackedLeg(competitor, leg);
if (trackedLeg != null && trackedLeg.hasStartedLeg(timePoint)) {
legEntry = createLegEntry(trackedLeg, timePoint, waitForLatestAnalyses, legRanksCache);
@@ -1,9 +1,7 @@
package com.sap.sailing.server.gateway.serialization.racegroup.impl;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.racegroup.RaceCell;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
@@ -14,11 +12,9 @@ public class RaceCellJsonSerializer implements JsonSerializer<RaceCell> {
public static final String FIELD_COMPETITORS = "competitors";
private JsonSerializer<RaceLog> logSerializer;
private JsonSerializer<Competitor> competitorSerializer;
public RaceCellJsonSerializer(JsonSerializer<RaceLog> logSerializer, JsonSerializer<Competitor> competitorSerializer) {
public RaceCellJsonSerializer(JsonSerializer<RaceLog> logSerializer) {
this.logSerializer = logSerializer;
this.competitorSerializer = competitorSerializer;
}
@Override
@@ -27,18 +23,8 @@ public class RaceCellJsonSerializer implements JsonSerializer<RaceCell> {
result.put(FIELD_NAME, object.getName());
result.put(FIELD_RACE_LOG, logSerializer.serialize(object.getRaceLog()));
JSONArray competitorArray = getJSONCompetitorArray(object);
result.put(FIELD_COMPETITORS, competitorArray);
return result;
}
private JSONArray getJSONCompetitorArray(RaceCell object) {
JSONArray competitorArray = new JSONArray();
for (Competitor competitor : object.getCompetitors()) {
competitorArray.add(competitorSerializer.serialize(competitor));
}
return competitorArray;
}
}
@@ -50,6 +50,15 @@
<url-pattern>/rc/currentcourse</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RCCompetitors</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.rc.CompetitorsJsonExportServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RCCompetitors</servlet-name>
<url-pattern>/rc/competitors</url-pattern>
</servlet-mapping>
<!-- RACE COMMITTEE END -->
<servlet>
@@ -0,0 +1,86 @@
package com.sap.sailing.server.gateway.impl.rc;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONArray;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
import com.sap.sailing.server.gateway.serialization.racegroup.impl.CompetitorJsonSerializer;
public class CompetitorsJsonExportServlet extends AbstractJsonHttpServlet {
private static final long serialVersionUID = 4510175441769759252L;
public static final String PARAMS_LEADERBOARD_NAME = "leaderboard";
public static final String PARAMS_RACE_COLUMN_NAME = "raceColumn";
public static final String PARAMS_RACE_FLEET_NAME = "fleet";
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String leaderboardName = request.getParameter(PARAMS_LEADERBOARD_NAME);
if (leaderboardName == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
String.format("Missing parameter '%s'.", PARAMS_LEADERBOARD_NAME));
return;
}
String raceColumnName = request.getParameter(PARAMS_RACE_COLUMN_NAME);
if (raceColumnName == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
String.format("Missing parameter '%s'.", PARAMS_RACE_COLUMN_NAME));
return;
}
String fleetName = request.getParameter(PARAMS_RACE_FLEET_NAME);
if (fleetName == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
String.format("Missing parameter '%s'.", PARAMS_RACE_FLEET_NAME));
return;
}
RacingEventService service = getService();
Leaderboard leaderboard = service.getLeaderboardByName(leaderboardName);
if (leaderboard == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "No such leaderboard found.");
return;
}
RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
if (raceColumn == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "No such race column found.");
return;
}
Fleet fleet = raceColumn.getFleetByName(fleetName);
if (fleet == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "No such fleet found.");
return;
}
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
JSONArray result = new JSONArray();
if (trackedRace != null) {
CompetitorJsonSerializer serializer = new CompetitorJsonSerializer();
for (Competitor competitor : raceColumn.getRaceDefinition(fleet).getCompetitors()) {
result.add(serializer.serialize(competitor));
}
}
result.writeJSONString(response.getWriter());
response.setContentType("application/json");
}
}
@@ -8,7 +8,6 @@ import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
@@ -24,7 +23,6 @@ import com.sap.sailing.domain.base.racegroup.impl.RaceGroupImpl;
import com.sap.sailing.domain.base.racegroup.impl.RaceRowImpl;
import com.sap.sailing.domain.base.racegroup.impl.SeriesWithRowsImpl;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
@@ -79,11 +77,7 @@ public class RaceGroupFactory {
Collection<RaceCell> cells = new ArrayList<>();
for (RaceColumn raceColumn : raceColumns) {
Fleet fleet = raceColumn.getFleetByName(fleetName);
Collection<Competitor> competitors = new ArrayList<Competitor>();
if (raceColumn.getRaceDefinition(fleet) != null) {
Util.addAll(raceColumn.getRaceDefinition(fleet).getCompetitors(), competitors);
}
cells.add(new RaceCellImpl(raceColumn.getName(), raceColumn.getRaceLog(fleet), competitors));
cells.add(new RaceCellImpl(raceColumn.getName(), raceColumn.getRaceLog(fleet)));
}
return cells;
}
@@ -81,7 +81,7 @@ public class RaceGroupJsonExportServlet extends AbstractJsonHttpServlet {
return new RaceGroupJsonSerializer(new BoatClassJsonSerializer(), new CourseAreaJsonSerializer(),
new SeriesWithRowsOfRaceGroupSerializer(new SeriesWithRowsJsonSerializer(
new RaceRowsOfSeriesWithRowsSerializer(new RaceRowJsonSerializer(new FleetJsonSerializer(
new ColorJsonSerializer()), new RaceCellJsonSerializer(createRaceLogSerializer(), new CompetitorJsonSerializer()))))));
new ColorJsonSerializer()), new RaceCellJsonSerializer(createRaceLogSerializer()))))));
}
@@ -89,7 +89,7 @@ public class OfflineDataManager extends DataManager {
new FleetImpl("Default"),
qualifying,
raceGroup),
log, competitors);
log);
log = new PassAwareRaceLogImpl();
/*log.add(factory.createStartTimeEvent(
@@ -105,7 +105,7 @@ public class OfflineDataManager extends DataManager {
new FleetImpl("Default"),
qualifying,
raceGroup),
log, competitors);
log);
log = new PassAwareRaceLogImpl();
/*log.add(factory.createRaceStatusEvent(
@@ -118,7 +118,7 @@ public class OfflineDataManager extends DataManager {
new FleetImpl("Default"),
qualifying,
raceGroup),
log, competitors);
log);
/*ManagedRace m1 = new ManagedRaceImpl(
new ManagedRaceIdentifierImpl(
"M1",
@@ -164,4 +164,9 @@ public class OfflineDataManager extends DataManager {
client.onLoadSucceded(managedRace.getCourseOnServer());
}
@Override
public void loadCompetitors(ManagedRace managedRace, LoadClient<Collection<Competitor>> client) {
client.onLoadSucceded((Collection<Competitor>) managedRace.getCompetitors());
}
}
@@ -10,6 +10,7 @@ import java.util.Collection;
import android.content.Context;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.EventBase;
@@ -17,12 +18,14 @@ import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
import com.sap.sailing.racecommittee.app.data.handlers.CompetitorsDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.CourseDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.DataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.EventsDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.ManagedRacesDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.MarksDataHandler;
import com.sap.sailing.racecommittee.app.data.loaders.DataLoader;
import com.sap.sailing.racecommittee.app.data.parsers.CompetitorsDataParser;
import com.sap.sailing.racecommittee.app.data.parsers.CourseDataParser;
import com.sap.sailing.racecommittee.app.data.parsers.DataParser;
import com.sap.sailing.racecommittee.app.data.parsers.EventsDataParser;
@@ -142,7 +145,7 @@ public class OnlineDataManager extends DataManager {
DataParser<Collection<ManagedRace>> parser = new ManagedRacesDataParser(new RaceGroupDeserializer(
boatClassDeserializer, new SeriesWithRowsDeserializer(new RaceRowDeserializer(new FleetDeserializer(
new ColorDeserializer()), new RaceCellDeserializer(
new RaceLogDeserializer(RaceLogEventDeserializer.create(domainFactory)), new CompetitorDeserializer(domainFactory))))));
new RaceLogDeserializer(RaceLogEventDeserializer.create(domainFactory)))))));
DataHandler<Collection<ManagedRace>> handler = new ManagedRacesDataHandler(this, client);
try {
@@ -215,4 +218,29 @@ public class OnlineDataManager extends DataManager {
e.printStackTrace();
}
}
@Override
public void loadCompetitors(ManagedRace managedRace, LoadClient<Collection<Competitor>> client) {
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorDeserializer(domainFactory);
DataParser<Collection<Competitor>> parser = new CompetitorsDataParser(competitorDeserializer);
DataHandler<Collection<Competitor>> handler = new CompetitorsDataHandler(this, client, managedRace);
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
String raceGroupName = URLEncoder.encode(identifier.getRaceGroup().getName());
String raceColumnName = URLEncoder.encode(identifier.getRaceName());
String fleetName = URLEncoder.encode(identifier.getFleet().getName());
try {
new DataLoader<Collection<Competitor>>(context, URI.create(AppConstants.getServerBaseURL(context)
+ "/sailingserver/rc/competitors?leaderboard=" + raceGroupName + "&raceColumn=" + raceColumnName
+ "&fleet=" + fleetName), parser, handler)
.forceLoad();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -3,6 +3,7 @@ package com.sap.sailing.racecommittee.app.data;
import java.io.Serializable;
import java.util.Collection;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.EventBase;
@@ -23,4 +24,6 @@ public interface ReadonlyDataManager {
public void loadMarks(ManagedRace managedRace, LoadClient<Collection<Mark>> client);
public void loadCourse(ManagedRace managedRace, LoadClient<CourseBase> client);
public void loadCompetitors(ManagedRace managedRace, LoadClient<Collection<Competitor>> client);
}
@@ -0,0 +1,25 @@
package com.sap.sailing.racecommittee.app.data.handlers;
import java.util.Collection;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
public class CompetitorsDataHandler extends DataHandler<Collection<Competitor>> {
private ManagedRace race;
public CompetitorsDataHandler(OnlineDataManager manager, LoadClient<Collection<Competitor>> client, ManagedRace managedRace) {
super(manager, client);
race = managedRace;
}
@Override
public void onLoaded(Collection<Competitor> data) {
super.onLoaded(data);
race.setCompetitors(data);
}
}
@@ -0,0 +1,37 @@
package com.sap.sailing.racecommittee.app.data.parsers;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
public class CompetitorsDataParser implements DataParser<Collection<Competitor>> {
private JsonDeserializer<Competitor> deserializer;
public CompetitorsDataParser(JsonDeserializer<Competitor> deserializer) {
this.deserializer = deserializer;
}
public Collection<Competitor> parse(Reader reader) throws Exception {
Object parsedResult = JSONValue.parseWithException(reader);
JSONArray jsonArray = Helpers.toJSONArraySafe(parsedResult);
Collection<Competitor> competitors = new ArrayList<Competitor>();
for (Object element : jsonArray) {
JSONObject json = Helpers.toJSONObjectSafe(element);
Competitor competitor = deserializer.deserialize(json);
competitors.add(competitor);
}
return competitors;
}
}
@@ -8,7 +8,6 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.racegroup.RaceCell;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
@@ -60,8 +59,7 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
series,
fleet,
cell.getName(),
log,
cell.getCompetitors());
log);
target.add(race);
}
}
@@ -69,11 +67,11 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
}
private ManagedRace createManagedRace(RaceGroup raceGroup, SeriesWithRows series,
Fleet fleet, String name, PassAwareRaceLog raceLog, Iterable<Competitor> competitors) {
Fleet fleet, String name, PassAwareRaceLog raceLog) {
return new ManagedRaceImpl(
new ManagedRaceIdentifierImpl(name,
new FleetIdentifierImpl(fleet, series, raceGroup)),
raceLog, competitors);
raceLog);
}
@@ -1,12 +1,7 @@
package com.sap.sailing.racecommittee.app.deserialization.impl;
import java.util.ArrayList;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.racegroup.RaceCell;
import com.sap.sailing.domain.base.racegroup.impl.RaceCellImpl;
import com.sap.sailing.domain.racelog.RaceLog;
@@ -18,11 +13,9 @@ import com.sap.sailing.server.gateway.serialization.racegroup.impl.RaceCellJsonS
public class RaceCellDeserializer implements JsonDeserializer<RaceCell> {
private JsonDeserializer<RaceLog> logDeserializer;
private JsonDeserializer<Competitor> competitorDeserializer;
public RaceCellDeserializer(JsonDeserializer<RaceLog> logDeserializer, JsonDeserializer<Competitor> competitorDeserializer) {
public RaceCellDeserializer(JsonDeserializer<RaceLog> logDeserializer) {
this.logDeserializer = logDeserializer;
this.competitorDeserializer = competitorDeserializer;
}
public RaceCell deserialize(JSONObject object)
@@ -32,20 +25,8 @@ public class RaceCellDeserializer implements JsonDeserializer<RaceCell> {
JSONObject logJson = Helpers.getNestedObjectSafe(object, RaceCellJsonSerializer.FIELD_RACE_LOG);
RaceLog log = logDeserializer.deserialize(logJson);
List<Competitor> competitors = deserializeCompetitorList(object);
return new RaceCellImpl(name, log, competitors);
}
private List<Competitor> deserializeCompetitorList(JSONObject object) throws JsonDeserializationException {
List<Competitor> competitors = new ArrayList<Competitor>();
JSONArray competitorsJson = Helpers.getNestedArraySafe(object, RaceCellJsonSerializer.FIELD_COMPETITORS);
for (Object competitorObject : competitorsJson) {
JSONObject jsonObject = (JSONObject) competitorObject;
Competitor competitor = competitorDeserializer.deserialize(jsonObject);
competitors.add(competitor);
}
return competitors;
return new RaceCellImpl(name, log);
}
}
@@ -1,5 +1,7 @@
package com.sap.sailing.racecommittee.app.domain;
import java.util.Collection;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.common.Named;
@@ -44,10 +46,16 @@ public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
* returns the list of competitors for this race
* @return list of competitors
*/
public Iterable<Competitor> getCompetitors();
public Collection<Competitor> getCompetitors();
public CourseBase getCourseOnServer();
public void setCourseOnServer(CourseBase course);
/**
* sets the list of competitors for a race. As the competitors are retrieved later from the backend, the list of competitors has to be settable.
* @param competitors the retrieved list of competitors for this race
*/
public void setCompetitors(Collection<Competitor> competitors);
}
@@ -1,6 +1,8 @@
package com.sap.sailing.racecommittee.app.domain.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
@@ -23,20 +25,20 @@ public class ManagedRaceImpl implements ManagedRace {
private ManagedRaceIdentifier identifier;
private RaceState state;
private Iterable<Competitor> competitors;
private Collection<Competitor> competitors;
private CourseBase courseOnServer;
public ManagedRaceImpl(ManagedRaceIdentifier identifier, PassAwareRaceLog raceLog, Iterable<Competitor> competitors) {
public ManagedRaceImpl(ManagedRaceIdentifier identifier, PassAwareRaceLog raceLog) {
//TODO To be changed when the start procedure for a regatta/leaderboard can be selected in the GWT Admin Console on backend side
this(identifier, new RaceStateImpl(raceLog, new GateStartProcedure(raceLog)), competitors);
this(identifier, new RaceStateImpl(raceLog, new GateStartProcedure(raceLog)));
}
public ManagedRaceImpl(
ManagedRaceIdentifier identifier,
RaceState state, Iterable<Competitor> competitors) {
RaceState state) {
this.identifier = identifier;
this.state = state;
this.competitors = competitors;
this.competitors = new ArrayList<Competitor>();
this.courseOnServer = null;
}
@@ -86,7 +88,7 @@ public class ManagedRaceImpl implements ManagedRace {
}
@Override
public Iterable<Competitor> getCompetitors() {
public Collection<Competitor> getCompetitors() {
return competitors;
}
@@ -100,4 +102,9 @@ public class ManagedRaceImpl implements ManagedRace {
courseOnServer = course;
}
@Override
public void setCompetitors(Collection<Competitor> competitors) {
this.competitors = competitors;
}
}
@@ -1,6 +1,7 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import java.util.Date;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.content.DialogInterface;
@@ -64,7 +65,7 @@ public class FinishingRaceFragment extends RaceFragment {
});
}
protected void setCountdownLabels(long millisecondsSinceStart) {
setStarttimeCountupLabel(millisecondsSinceStart);
}
@@ -2,6 +2,7 @@ package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -27,6 +28,8 @@ import com.sap.sailing.domain.common.Named;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
import com.sap.sailing.racecommittee.app.domain.impl.DomainFactoryImpl;
import com.sap.sailing.racecommittee.app.logging.ExLog;
import com.sap.sailing.racecommittee.app.ui.adapters.finishing.CompetitorPositioningListAdapter;
@@ -87,6 +90,7 @@ public class PositioningFragment extends RaceDialogFragment {
Collections.sort(competitors, competitorComparator);
competitorsAdapter = new CompetitorsAdapter(getActivity(), R.layout.welter_grid_competitor_cell, competitors);
loadCompetitors();
positionedCompetitors = initializeFinishPositioningList();
deletePositionedCompetitorsFromUnpositionedList();
@@ -142,6 +146,12 @@ public class PositioningFragment extends RaceDialogFragment {
});
}
@Override
public void onResume() {
super.onResume();
onLoadCompetitorsSucceeded(getRace().getCompetitors());
}
/**
* Creates a DragSortController and thereby defines the behaviour of the drag sort list
*/
@@ -156,7 +166,32 @@ public class PositioningFragment extends RaceDialogFragment {
controller.setBackgroundColor(getActivity().getResources().getColor(R.color.welter_medium_blue));
return controller;
}
private void loadCompetitors() {
OnlineDataManager.create(getActivity()).loadCompetitors(getRace(), new LoadClient<Collection<Competitor>>() {
@Override
public void onLoadFailed(Exception reason) {
onLoadCompetitorsSucceeded(getRace().getCompetitors());
}
@Override
public void onLoadSucceded(Collection<Competitor> data) {
onLoadCompetitorsSucceeded(data);
}
});
}
protected void onLoadCompetitorsSucceeded(Collection<Competitor> data) {
competitors.clear();
competitors.addAll(data);
Collections.sort(competitors, competitorComparator);
deletePositionedCompetitorsFromUnpositionedList();
competitorsAdapter.notifyDataSetChanged();
}
private void deletePositionedCompetitorsFromUnpositionedList() {
for (Triple<Serializable, String, MaxPointsReason> positionedItem : positionedCompetitors) {
Competitor competitor = DomainFactoryImpl.INSTANCE.getExistingCompetitorById(positionedItem.getA());