From 9ab84c5eb090095587d27c52604abc1c59ecafa0 Mon Sep 17 00:00:00 2001 From: Lukas Niemeier Date: Wed, 6 Feb 2013 17:33:49 +0100 Subject: [PATCH] # working towards receiving racelogs... --- .../WEB-INF/web.xml | 8 +- ...et.java => RaceLogsJsonExportServlet.java} | 90 +++++++++++-------- .../racecommittee/app/AppConstants.java | 2 +- .../app/data/DataLoadingException.java | 21 +++++ .../racecommittee/app/data/DataManager.java | 70 +++++++++++++-- .../app/data/ReadonlyDataManager.java | 6 ++ .../app/data/handlers/EventsDataHandler.java | 7 -- ...etHttpRequest.java => HttpGetRequest.java} | 13 +-- .../app/data/http/HttpJsonPostRequest.java | 37 ++++++++ .../app/data/http/HttpRequest.java | 26 +++--- .../app/data/loaders/DataLoader.java | 17 ++-- .../data/parsers/ManagedRacesDataParser.java | 4 +- .../app/domain/FleetIdentifier.java | 18 ++++ .../app/domain/ManagedRaceIdentifier.java | 15 +--- ...fierImpl.java => FleetIdentifierImpl.java} | 20 ++--- .../app/domain/impl/RaceIdentifierImpl.java | 37 ++++++++ .../racecommittee/app/logging/ExLog.java | 2 +- .../app/ui/activities/RacingActivity.java | 74 ++++++++++----- .../{ => racelist}/RaceListAdapter.java | 8 +- .../racelist/RaceListDataTypeElement.java | 10 +-- .../list/ManagedRaceListFragment.java | 85 +++++++++++------- .../ui/fragments/list/NamedListFragment.java | 2 +- .../app/utils/AlphanumComparator.java | 8 -- 23 files changed, 401 insertions(+), 179 deletions(-) rename java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/{EventTrackJsonExportServlet.java => RaceLogsJsonExportServlet.java} (83%) create mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataLoadingException.java rename mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/{GetHttpRequest.java => HttpGetRequest.java} (55%) create mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpJsonPostRequest.java create mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/FleetIdentifier.java rename mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/impl/{ManagedRaceIdentifierImpl.java => FleetIdentifierImpl.java} (62%) create mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/impl/RaceIdentifierImpl.java rename mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/{ => racelist}/RaceListAdapter.java (94%) diff --git a/java/com.sap.sailing.server.gateway/WEB-INF/web.xml b/java/com.sap.sailing.server.gateway/WEB-INF/web.xml index 73e0a3f4fc0..da021315194 100644 --- a/java/com.sap.sailing.server.gateway/WEB-INF/web.xml +++ b/java/com.sap.sailing.server.gateway/WEB-INF/web.xml @@ -35,12 +35,12 @@ - RCEventTrack - com.sap.sailing.server.gateway.impl.rc.EventTrackJsonExportServlet + RCRaceLogs + com.sap.sailing.server.gateway.impl.rc.RaceLogsJsonExportServlet - RCEventTrack - /rc/eventTrack + RCRaceLogs + /rc/racelogs diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/EventTrackJsonExportServlet.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceLogsJsonExportServlet.java similarity index 83% rename from java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/EventTrackJsonExportServlet.java rename to java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceLogsJsonExportServlet.java index 6756fd852e0..8469b2baf32 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/EventTrackJsonExportServlet.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/RaceLogsJsonExportServlet.java @@ -7,16 +7,18 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.simple.JSONArray; +import org.json.simple.JSONValue; +import org.json.simple.parser.ParseException; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.common.RegattaNameAndRaceName; -import com.sap.sailing.domain.racelog.RaceLog; import com.sap.sailing.domain.racelog.RaceLogEvent; import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.DynamicTrackedRegatta; -import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; +import com.sap.sailing.server.gateway.deserialization.impl.Helpers; import com.sap.sailing.server.gateway.impl.JsonExportServlet; import com.sap.sailing.server.gateway.serialization.JsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.CompetitorIdJsonSerializer; @@ -26,10 +28,58 @@ import com.sap.sailing.server.gateway.serialization.impl.racelog.RaceLogFlagEven import com.sap.sailing.server.gateway.serialization.impl.racelog.RaceLogStartTimeEventSerializer; -public class EventTrackJsonExportServlet extends JsonExportServlet { +public class RaceLogsJsonExportServlet extends JsonExportServlet { private static final long serialVersionUID = 2197006949440887925L; - + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + try { + Object requestBody = JSONValue.parseWithException(request.getReader()); + JSONArray requestedIds = Helpers.toJSONArraySafe(requestBody); + + for (Object element : requestedIds) { + System.out.println(element); + } + + } catch (ParseException e) { + throw new JsonDeserializationException("Invalid JSON in request body.", e); + } + + } + + + private DynamicTrackedRace getDynamicTrackedRace(String regattaName, String raceName) { + RegattaNameAndRaceName raceAndRegattaIdentifier = new RegattaNameAndRaceName(regattaName, raceName); + + RaceDefinition raceDefinition = getService().getRace(raceAndRegattaIdentifier); + Regatta regatta = getService().getRegatta(raceAndRegattaIdentifier); + + DynamicTrackedRegatta trackedRegatta = getService().getTrackedRegatta(regatta); + DynamicTrackedRace trackedRace = trackedRegatta.getExistingTrackedRace(raceDefinition); + + return trackedRace; + } + + private boolean validateParameter(HttpServletResponse response, String... parameters) throws IOException { + for (String parameter : parameters) { + if (parameter == null) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return false; + } + } + return true; + } + + private static JsonSerializer createSerializer() { + JsonSerializer competitorSerializer = new CompetitorIdJsonSerializer(); + return new RaceLogEventSerializer( + new RaceLogFlagEventSerializer(competitorSerializer), + new RaceLogStartTimeEventSerializer(competitorSerializer), + new RaceLogCourseAreaChangedEventSerializer(competitorSerializer)); + } + /*@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -77,36 +127,6 @@ public class EventTrackJsonExportServlet extends JsonExportServlet { // trackedRace.recordRaceCommitteeEvent(null); response.sendError(HttpServletResponse.SC_NO_CONTENT); - } - - private DynamicTrackedRace getDynamicTrackedRace(String regattaName, String raceName) { - RegattaNameAndRaceName raceAndRegattaIdentifier = new RegattaNameAndRaceName(regattaName, raceName); - - RaceDefinition raceDefinition = getService().getRace(raceAndRegattaIdentifier); - Regatta regatta = getService().getRegatta(raceAndRegattaIdentifier); - - DynamicTrackedRegatta trackedRegatta = getService().getTrackedRegatta(regatta); - DynamicTrackedRace trackedRace = trackedRegatta.getExistingTrackedRace(raceDefinition); - - return trackedRace; - } - - private boolean validateParameter(HttpServletResponse response, String... parameters) throws IOException { - for (String parameter : parameters) { - if (parameter == null) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return false; - } - } - return true; - } - - private static JsonSerializer createSerializer() { - JsonSerializer competitorSerializer = new CompetitorIdJsonSerializer(); - return new RaceLogEventSerializer( - new RaceLogFlagEventSerializer(competitorSerializer), - new RaceLogStartTimeEventSerializer(competitorSerializer), - new RaceLogCourseAreaChangedEventSerializer(competitorSerializer)); - } + }*/ } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java index f7e4a358996..496cc1763d7 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java @@ -17,7 +17,7 @@ public class AppConstants { // Intent extra fields public final static String COURSE_AREA_UUID_KEY = "courseUuid"; - public final static String RACE_UUID_KEY = "raceUuid"; + public final static String RACE_ID_KEY = "raceUuid"; public final static String SERVICE_UNIQUE_ID = "serviceUID"; public final static String RACING_EVENT_TIME = "racingEventTime"; public final static String EXTRAS_JSON_KEY = "json"; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataLoadingException.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataLoadingException.java new file mode 100644 index 00000000000..12b89697874 --- /dev/null +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataLoadingException.java @@ -0,0 +1,21 @@ +package com.sap.sailing.racecommittee.app.data; + +public class DataLoadingException extends Exception { + private static final long serialVersionUID = 4787160523984332591L; + + public DataLoadingException() { + } + + public DataLoadingException(String detailMessage) { + super(detailMessage); + } + + public DataLoadingException(Throwable throwable) { + super(throwable); + } + + public DataLoadingException(String detailMessage, Throwable throwable) { + super(detailMessage, throwable); + } + +} diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java index faa0b8a7b9b..6e6664054bc 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java @@ -1,17 +1,24 @@ package com.sap.sailing.racecommittee.app.data; import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.util.ArrayList; import java.util.Collection; +import java.util.Map; + +import org.json.simple.JSONValue; import android.content.Context; import com.sap.sailing.domain.base.CourseArea; import com.sap.sailing.domain.base.Event; +import com.sap.sailing.domain.racelog.RaceLogEvent; import com.sap.sailing.racecommittee.app.data.clients.LoadClient; 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.http.HttpJsonPostRequest; import com.sap.sailing.racecommittee.app.data.loaders.DataLoader; import com.sap.sailing.racecommittee.app.data.parsers.DataParser; import com.sap.sailing.racecommittee.app.data.parsers.EventsDataParser; @@ -25,11 +32,13 @@ import com.sap.sailing.racecommittee.app.domain.deserialization.impl.FleetWithRa import com.sap.sailing.racecommittee.app.domain.deserialization.impl.RaceGroupDeserializer; import com.sap.sailing.racecommittee.app.domain.deserialization.impl.SeriesDataDeserializer; import com.sap.sailing.racecommittee.app.domain.deserialization.impl.VenueJsonDeserializer; +import com.sap.sailing.racecommittee.app.logging.ExLog; /** * Enables accessing of data. */ public class DataManager implements ReadonlyDataManager { + private static final String TAG = DataManager.class.getName(); public static ReadonlyDataManager create(Context context) { return new DataManager(context, InMemoryDataStore.INSTANCE); @@ -74,22 +83,37 @@ public class DataManager implements ReadonlyDataManager { DataLoader> loader = new DataLoader>( context, - URI.create("http://192.168.178.22:8888/sailingserver/rc/events"), + URI.create(TargetHost + "/sailingserver/rc/events"), parser, handler); loader.forceLoad(); } - public void loadCourseAreas(Serializable parentEventId, - LoadClient> client) { + public void loadCourseAreas( + final Serializable parentEventId, + final LoadClient> client) { if (dataStore.hasEvent(parentEventId)) { Event event = dataStore.getEvent(parentEventId); client.onLoadSucceded(dataStore.getCourseAreas(event)); } else { - client.onLoadFailed(new IllegalStateException("Unknown event id...")); + reloadEvents(new LoadClient>() { + public void onLoadSucceded(Collection data) { + if (dataStore.hasEvent(parentEventId)) { + Event event = dataStore.getEvent(parentEventId); + client.onLoadSucceded(dataStore.getCourseAreas(event)); + } else { + client.onLoadFailed(new DataLoadingException( + String.format("There was no event object found for id %s.", parentEventId))); + } + } + + public void onLoadFailed(Exception reason) { + client.onLoadFailed(new DataLoadingException( + String.format("There was no event object found for id %s. While reloading the events an error occured: %s", parentEventId, reason), reason)); + } + }); } - } public void addRaces(Collection data) { @@ -101,7 +125,7 @@ public class DataManager implements ReadonlyDataManager { public void loadRaces(Serializable courseAreaId, LoadClient> client) { if (!dataStore.hasCourseArea(courseAreaId)) { - client.onLoadFailed(new IllegalStateException("No course area found with given id")); + client.onLoadFailed(new DataLoadingException(String.format("No course area found with id %s", courseAreaId))); return; } @@ -116,12 +140,44 @@ public class DataManager implements ReadonlyDataManager { DataLoader> loader = new DataLoader>( context, - URI.create("http://192.168.178.22:8888/sailingserver/rc/leaderboards?courseArea=" + courseAreaId.toString()), + URI.create(TargetHost + "/sailingserver/rc/leaderboards?courseArea=" + courseAreaId.toString()), parser, handler); loader.forceLoad(); } + + public void loadRaceLogs( + Collection data, + LoadClient>> client) { + Collection ids = new ArrayList(); + for (ManagedRace race : data) { + if (!dataStore.hasRace(race.getId())) { + ExLog.w(TAG, "Tried to load race log for unknown race " + race.getId()); + continue; + } + ids.add(race.getId()); + } + + HttpJsonPostRequest request = null; + try { + String value = JSONValue.toJSONString(ids); + ExLog.e(TAG, value); + request = new HttpJsonPostRequest(URI.create(TargetHost + "sailingserver/rc/racelogs"), value); + } catch (UnsupportedEncodingException e) { + ExLog.e(TAG, "Exception while trying to create POST request. Aborting:\n" + e); + return; + } + + /*DataLoader>> loader = + new DataLoader>>( + context, + request, + null, + null);*/ + } + + private static final String TargetHost = "http://192.168.42.100:8888"; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java index bdf404699c9..cf6cf82a5d9 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java @@ -2,9 +2,11 @@ package com.sap.sailing.racecommittee.app.data; import java.io.Serializable; import java.util.Collection; +import java.util.Map; import com.sap.sailing.domain.base.CourseArea; import com.sap.sailing.domain.base.Event; +import com.sap.sailing.domain.racelog.RaceLogEvent; import com.sap.sailing.racecommittee.app.data.clients.LoadClient; import com.sap.sailing.racecommittee.app.domain.ManagedRace; @@ -16,5 +18,9 @@ public interface ReadonlyDataManager { public void loadCourseAreas(Serializable parentEventId, LoadClient> client); public void loadRaces(Serializable courseAreaId, LoadClient> client); + + public void loadRaceLogs( + Collection data, + LoadClient>> client); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/EventsDataHandler.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/EventsDataHandler.java index 08fc5d95cdb..864f67b8003 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/EventsDataHandler.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/EventsDataHandler.java @@ -1,11 +1,8 @@ package com.sap.sailing.racecommittee.app.data.handlers; import java.util.Collection; -import java.util.UUID; import com.sap.sailing.domain.base.Event; -import com.sap.sailing.domain.base.impl.CourseAreaImpl; -import com.sap.sailing.domain.base.impl.EventImpl; import com.sap.sailing.racecommittee.app.data.DataManager; import com.sap.sailing.racecommittee.app.data.clients.LoadClient; @@ -17,10 +14,6 @@ public class EventsDataHandler extends DataHandler> { @Override public void onLoaded(Collection data) { - Event testEvet = new EventImpl("Test Event", "Berlin", "http://example.com", true, UUID.randomUUID()); - testEvet.getVenue().addCourseArea(new CourseAreaImpl("Test Area", UUID.randomUUID())); - data.add(testEvet); - super.onLoaded(data); manager.addEvents(data); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/GetHttpRequest.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpGetRequest.java similarity index 55% rename from mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/GetHttpRequest.java rename to mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpGetRequest.java index 3f6f5f835ac..5b34c134448 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/GetHttpRequest.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpGetRequest.java @@ -7,13 +7,16 @@ import java.net.URI; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpRequestBase; -public class GetHttpRequest extends HttpRequest { +public class HttpGetRequest extends HttpRequest { - public InputStream get(URI requestUri) throws IOException { - HttpRequestBase get = new HttpGet(requestUri); - HttpResponse response = executeRequest(get); + + public HttpGetRequest(URI requestUri) { + super(new HttpGet(requestUri)); + } + + @Override + protected InputStream processResponse(HttpResponse response) throws IllegalStateException, IOException { HttpEntity entity = response.getEntity(); return entity.getContent(); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpJsonPostRequest.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpJsonPostRequest.java new file mode 100644 index 00000000000..512293e1e5b --- /dev/null +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpJsonPostRequest.java @@ -0,0 +1,37 @@ +package com.sap.sailing.racecommittee.app.data.http; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URI; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +public class HttpJsonPostRequest extends HttpRequest { + public final static String JsonUTF8 = "application/json;charset=UTF-8"; + + public HttpJsonPostRequest(URI requestUri, String body) throws UnsupportedEncodingException { + super(createPostRequest(requestUri, body)); + } + + private static HttpPost createPostRequest(URI requestUri, String body) throws UnsupportedEncodingException { + StringEntity entity = new StringEntity(body); + entity.setContentType(JsonUTF8); + entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, JsonUTF8)); + + HttpPost post = new HttpPost(requestUri); + post.setEntity(entity); + return post; + } + + @Override + protected InputStream processResponse(HttpResponse response) throws IllegalStateException, IOException { + HttpEntity entity = response.getEntity(); + return entity.getContent(); + } +} diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpRequest.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpRequest.java index 5880cefc755..41a407952e2 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpRequest.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/http/HttpRequest.java @@ -1,6 +1,7 @@ package com.sap.sailing.racecommittee.app.data.http; import java.io.IOException; +import java.io.InputStream; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -30,21 +31,24 @@ public abstract class HttpRequest { throw new IOException(String.format("Request response had no valid status.")); } - //protected final static String JsonUTF8 = "application/json;charset=UTF-8"; + private HttpClient client; + private HttpRequestBase httpRequestBase; - protected HttpClient client; - - public HttpRequest() { - client = new DefaultHttpClient(); + public HttpRequest(HttpRequestBase request) { + this.httpRequestBase = request; + this.client = new DefaultHttpClient(); } - - protected HttpResponse executeRequest(HttpRequestBase request) throws IOException { - ExLog.i(TAG, "Requesting " + request.getMethod() + " " + request.getURI().toString()); - HttpResponse response = client.execute(request); + protected abstract InputStream processResponse(HttpResponse response) throws Exception; + + public InputStream execute() throws Exception { + ExLog.i(TAG, "Executing request " + httpRequestBase.getMethod() + " on " + httpRequestBase.getURI()); + HttpResponse response = client.execute(httpRequestBase); validateHttpResponse(response); - ExLog.i(TAG, "Response " + response.getStatusLine().toString()); - return response; + ExLog.i(TAG, "Received reseponse " + response.getStatusLine()); + return processResponse(response); } + + diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/loaders/DataLoader.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/loaders/DataLoader.java index 1626967a3b8..6a91cd36ec2 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/loaders/DataLoader.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/loaders/DataLoader.java @@ -9,22 +9,28 @@ import android.content.AsyncTaskLoader; import android.content.Context; import com.sap.sailing.racecommittee.app.data.handlers.DataHandler; -import com.sap.sailing.racecommittee.app.data.http.GetHttpRequest; +import com.sap.sailing.racecommittee.app.data.http.HttpGetRequest; +import com.sap.sailing.racecommittee.app.data.http.HttpRequest; import com.sap.sailing.racecommittee.app.data.parsers.DataParser; import com.sap.sailing.racecommittee.app.logging.ExLog; public class DataLoader extends AsyncTaskLoader { private static final String TAG = DataLoader.class.getName(); - protected URI requestUri; protected DataParser dataParser; protected DataHandler dataHandler; + protected HttpRequest httpRequest; protected volatile Exception lastException; - public DataLoader(Context context, URI requestUri, + public DataLoader(Context context, URI httpGetUri, + DataParser dataParser, DataHandler dataHandler) { + this(context, new HttpGetRequest(httpGetUri), dataParser, dataHandler); + } + + public DataLoader(Context context, HttpRequest request, DataParser dataParser, DataHandler dataHandler) { super(context); - this.requestUri = requestUri; + this.httpRequest = request; this.dataParser = dataParser; this.dataHandler = dataHandler; } @@ -42,11 +48,10 @@ public class DataLoader extends AsyncTaskLoader { } private T loadDataInBackground() throws Exception { - GetHttpRequest getRequest = new GetHttpRequest(); InputStream inputStream = null; Reader inputReader = null; try { - inputStream = getRequest.get(requestUri); + inputStream = httpRequest.execute(); inputReader = new InputStreamReader(inputStream); return dataParser.parse(inputReader); } finally { diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java index e21dc8c5452..b8c3e46dd65 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java @@ -14,7 +14,7 @@ import com.sap.sailing.domain.base.RaceGroup; import com.sap.sailing.domain.base.SeriesData; import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier; -import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceIdentifierImpl; +import com.sap.sailing.racecommittee.app.domain.impl.RaceIdentifierImpl; import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceImpl; import com.sap.sailing.racecommittee.app.logging.ExLog; import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; @@ -72,7 +72,7 @@ public class ManagedRacesDataParser implements DataParser>() { public void onLoadSucceded(Collection data) { - setProgressBarIndeterminateVisibility(false); - - /// TODO: register races on SERVICE - /*registerOnService(races);*/ - listFragment.setupOn(data); - - Toast.makeText(RacingActivity.this, - "Loaded " + data.size() + " races for course " + courseAreaId.toString(), - Toast.LENGTH_LONG).show(); + onLoadRacesSucceded(courseAreaId, data); + } public void onLoadFailed(Exception reason) { - setProgressBarIndeterminateVisibility(false); - showLoadFailedDialog(courseAreaId, reason.getMessage()); + onLoadRacesFailed(courseAreaId, reason); } }); } + private void onLoadRacesSucceded(Serializable courseAreaId, Collection data) { + setProgressBarIndeterminateVisibility(false); + + dataManager.loadRaceLogs(data, new LoadClient>>() { + + public void onLoadSucceded(Map> data) { + // TODO Auto-generated method stub + + } + + public void onLoadFailed(Exception reason) { + ExLog.w(TAG, "Loading of race logs failed:\n" + reason.toString()); + } + }); + + registerOnService(data); + listFragment.setupOn(data); + + Toast.makeText(RacingActivity.this, + "Loaded " + data.size() + " races for course " + courseAreaId.toString(), + Toast.LENGTH_LONG).show(); + } + + private void onLoadRacesFailed(final Serializable courseAreaId, Exception reason) { + setProgressBarIndeterminateVisibility(false); + showLoadFailedDialog(courseAreaId, reason.getMessage()); + } + + private void registerOnService(Collection races) { + // since the service is the long-living component + // he should decide whether these races are already + // registered or not. + for (ManagedRace race : races) { + Intent registerIntent = new Intent(AppConstants.REGISTER_RACE_ACTION); + registerIntent.putExtra(AppConstants.RACE_ID_KEY, race.getId()); + this.startService(registerIntent); + } + } + private void showLoadFailedDialog(final Serializable courseId, String message) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(String.format("There was an error loading the requested data: %s\nDo you want to retry?", message)) @@ -142,6 +177,10 @@ StartModeSelectionListener, PathfinderSelectionListener, GateLineOpeningTimeSele AlertDialog alert = builder.create(); alert.show(); } + + public void onRaceItemClicked(ManagedRace race) { + + } /*public void onRaceItemClicked(ManagedRace race) { infoFragment = new RaceInfoFragment(); @@ -163,17 +202,6 @@ StartModeSelectionListener, PathfinderSelectionListener, GateLineOpeningTimeSele transaction.setTransition(FragmentTransaction.TRANSIT_NONE); transaction.commit(); } - - /*private void registerOnService(List races) { - // since the service is the long-living component - // he should decide whether these races are already - // registered or not. - for (ManagedRace race : races) { - Intent registerIntent = new Intent(AppConstants.REGISTER_RACE_ACTION); - registerIntent.putExtra(AppConstants.RACE_UUID_KEY, race.getId()); - RacingActivity.this.startService(registerIntent); - } - }*/ /*public void onResetTimeClick() { infoFragment.displayResetTimeFragment(); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/RaceListAdapter.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/RaceListAdapter.java similarity index 94% rename from mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/RaceListAdapter.java rename to mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/RaceListAdapter.java index f8ae342f1e4..915136c6faa 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/RaceListAdapter.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/RaceListAdapter.java @@ -1,4 +1,4 @@ -package com.sap.sailing.racecommittee.app.ui.adapters; +package com.sap.sailing.racecommittee.app.ui.adapters.racelist; import java.util.ArrayList; import java.util.Collections; @@ -19,10 +19,6 @@ import android.widget.TextView; import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.domain.RaceStatus; -import com.sap.sailing.racecommittee.app.ui.adapters.racelist.BoatClassSeriesDataFleet; -import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListDataType; -import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListDataTypeElement; -import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListDataTypeTitle; import com.sap.sailing.racecommittee.app.ui.comparators.RaceListDataTypeElementComparator; import com.sap.sailing.racecommittee.app.ui.comparators.RaceListDataTypeTitleComparator; @@ -126,7 +122,7 @@ public class RaceListAdapter extends ArrayAdapter { holder.line1.setText(element.getRaceName()); holder.line2.setText(element.getStatus()); - if (element.getUpdateIndicator()) { + if (element.isUpdateIndicatorVisible()) { holder.updateLabel.setVisibility(View.VISIBLE); } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/RaceListDataTypeElement.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/RaceListDataTypeElement.java index 7ddb77f3cf4..0eb1c7fe959 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/RaceListDataTypeElement.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/racelist/RaceListDataTypeElement.java @@ -8,7 +8,7 @@ import com.sap.sailing.racecommittee.app.domain.RaceStatus; public class RaceListDataTypeElement extends RaceListDataType { - private boolean updateIndicator = false; + private boolean updateIndicatorVisible = false; private ManagedRace race; private RaceStatus currentRaceStatus; @@ -44,12 +44,12 @@ public class RaceListDataTypeElement extends RaceListDataType { this.currentRaceStatus = race.getStatus(); } - public void setUpdateIndicator(boolean ui) { - this.updateIndicator = ui; + public void setUpdateIndicator(boolean visible) { + this.updateIndicatorVisible = visible; } - public boolean getUpdateIndicator() { - return updateIndicator; + public boolean isUpdateIndicatorVisible() { + return updateIndicatorVisible; } public String getRaceName() { diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/ManagedRaceListFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/ManagedRaceListFragment.java index 53a9726409f..a779e1b29d8 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/ManagedRaceListFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/ManagedRaceListFragment.java @@ -12,30 +12,33 @@ import java.util.TreeMap; import android.app.ListFragment; import android.os.Bundle; import android.view.View; +import android.widget.ImageView; import android.widget.ListView; import com.sap.sailing.domain.base.impl.BoatClassImpl; import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.domain.RaceStatus; -import com.sap.sailing.racecommittee.app.ui.adapters.RaceListAdapter; -import com.sap.sailing.racecommittee.app.ui.adapters.RaceListAdapter.JuryFlagClickedListener; +import com.sap.sailing.racecommittee.app.logging.ExLog; +import com.sap.sailing.racecommittee.app.ui.activities.RacingActivity; import com.sap.sailing.racecommittee.app.ui.adapters.racelist.BoatClassSeriesDataFleet; +import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListAdapter; import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListDataType; import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListDataTypeElement; import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListDataTypeTitle; +import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListAdapter.JuryFlagClickedListener; import com.sap.sailing.racecommittee.app.ui.comparators.NamedRaceComparator; import com.sap.sailing.racecommittee.app.ui.comparators.SeriesComparator; public class ManagedRaceListFragment extends ListFragment implements JuryFlagClickedListener { - //private Serializable selectedRaceId; + private Serializable selectedRaceId; private HashMap managedRacesById; private RaceListAdapter adapter; private ArrayList raceDataTypeList; public ManagedRaceListFragment() { - //this.selectedRaceId = null; + this.selectedRaceId = null; this.managedRacesById = new HashMap(); this.raceDataTypeList = new ArrayList(); } @@ -137,13 +140,57 @@ public class ManagedRaceListFragment extends ListFragment implements JuryFlagCli } @Override - public void onListItemClick(ListView l, View v, int position, long id) { - super.onListItemClick(l, v, position, id); - /// TODO: implement. + public void onListItemClick(ListView listView, View view, int position, long id) { + super.onListItemClick(listView, view, position, id); + + RaceListDataType selectedItem = adapter.getItem(position); + if (selectedItem instanceof RaceListDataTypeElement) { + RaceListDataTypeElement selectedElement = (RaceListDataTypeElement) selectedItem; + selectedElement.setUpdateIndicator(false); + ((ImageView) view.findViewById(R.id.Welter_Cell_UpdateLabel)).setVisibility(View.GONE); + + ManagedRace selectedRace = selectedElement.getRace(); + this.selectedRaceId = selectedRace.getId(); + + ExLog.i( + ExLog.RACE_SELECTED_ELEMENT, + selectedRace.getId() + " " + selectedRace.getStatus(), + getActivity()); + + ((RacingActivity) getActivity()).onRaceItemClicked(selectedRace); + + } else if (selectedItem instanceof RaceListDataTypeTitle) { + RaceListDataTypeTitle selectedTitle = (RaceListDataTypeTitle) selectedItem; + ExLog.i( + ExLog.RACE_SELECTED_TITLE, + selectedTitle.toString(), + getActivity()); + } } public void notifyDataChanged() { - /// TODO: implement. + List list = adapter.getItems(); + for (int i = 0; i < list.size(); ++i) { + if (list.get(i) instanceof RaceListDataTypeElement) { + RaceListDataTypeElement listElement = (RaceListDataTypeElement) list.get(i); + ManagedRace mr = this.managedRacesById.get(listElement.getRace().getId()); + if (mr != null) { + if (!listElement.getPreviousRaceStatus().name().equals(mr.getStatus().name())) { + listElement.setRace(mr); + + if (!listElement.getRace().getId().equals(this.selectedRaceId)) { + listElement.setUpdateIndicator(true); + } + /// TODO: StaticVibrator.vibrate(1000); + } + + } + } + } + if (adapter != null) { + adapter.getFilter().filter(""); + adapter.notifyDataSetChanged(); + } } public void onJuryFlagClicked(BoatClassSeriesDataFleet clicked) { @@ -152,28 +199,6 @@ public class ManagedRaceListFragment extends ListFragment implements JuryFlagCli /* - @Override - public void onListItemClick(ListView listView, View view, int position, - long id) { - super.onListItemClick(listView, view, position, id); - - // listener only for elements, not for titles - RaceListDataType element = adapter.getItem(position); - if (element instanceof RaceListDataTypeElement) { - - RaceListDataTypeElement rldte = (RaceListDataTypeElement) element; - selectedRaceId = rldte.getRace().getId(); - ManagedRace toLoad = managedRacesMap.get(rldte.getRace().getId()); - ExLog.i(ExLog.RACE_SELECTED_ELEMENT, rldte.getRace().getId().toString() + " " + rldte.getStatus(), getActivity()); - ((ImageView) view.findViewById(R.id.Welter_Cell_UpdateLabel)).setVisibility(View.GONE); - ((RacingActivity) getActivity()).onRaceItemClicked(toLoad); - rldte.setUpdateIndicator(false); - } else if (element instanceof RaceListDataTypeTitle) { - RaceListDataTypeTitle rlt = (RaceListDataTypeTitle) element; - ExLog.i(ExLog.RACE_SELECTED_LABEL, rlt.toString(), getActivity()); - } - - } public void notifyDataChanged() { List list = adapter.getItems(); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/NamedListFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/NamedListFragment.java index d5cd2791185..c7faf44aa09 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/NamedListFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/list/NamedListFragment.java @@ -113,7 +113,7 @@ public abstract class NamedListFragment extends ListFragment im private void showLoadFailedDialog(String message) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage(String.format("There was an error loading the requested data: %s\nDo you want to retry?", message)) + builder.setMessage(String.format("There was an error loading the requested data:\n%s\nDo you want to retry?", message)) .setTitle("Load failure") .setIcon(R.drawable.ic_dialog_alert_holo_light) .setCancelable(true) diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/AlphanumComparator.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/AlphanumComparator.java index e8edec52195..d1b2e62b8ca 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/AlphanumComparator.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/AlphanumComparator.java @@ -29,14 +29,6 @@ import java.util.Comparator; * This is an updated version with enhancements made by Daniel Migowski, * Andre Bogus, and David Koelle * - * To convert to use Templates (Java 1.5+): - * - Change "implements Comparator" to "implements Comparator" - * - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)" - * - Remove the type checking and casting in compare(). - * - * To use this class: - * Use the static "sort" method from the java.util.Collections class: - * Collections.sort(your list, new AlphanumComparator()); */ public class AlphanumComparator implements Comparator {