mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-19 02:29:58 +00:00
Merge remote-tracking branch 'origin/master' into leaderboardView2
This commit is contained in:
commit
daee1914a3
108 files changed
+2161
-933
No files matched your search
+20
-9
@@ -142,7 +142,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TimePoint loadTimePoint(DBObject object, FieldNames field) {
|
private TimePoint loadTimePoint(DBObject object, FieldNames field) {
|
||||||
return new MillisecondsTimePoint((Long) object.get(field.name()));
|
return new MillisecondsTimePoint(((Number) object.get(field.name())).longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1006,14 +1006,15 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
|||||||
RaceLog result = new RaceLogImpl(RaceLogImpl.class.getSimpleName(), identifier.getIdentifier());
|
RaceLog result = new RaceLogImpl(RaceLogImpl.class.getSimpleName(), identifier.getIdentifier());
|
||||||
try {
|
try {
|
||||||
BasicDBObject query = new BasicDBObject();
|
BasicDBObject query = new BasicDBObject();
|
||||||
query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(identifier.getIdentifier().toString()));
|
query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(identifier.getIdentifier()));
|
||||||
DBCollection raceLog = database.getCollection(CollectionNames.RACE_LOGS.name());
|
loadRaceLogEvents(result, query);
|
||||||
for (DBObject o : raceLog.find(query)) {
|
|
||||||
RaceLogEvent raceLogEvent = loadRaceLogEvent((DBObject) o.get(FieldNames.RACE_LOG_EVENT.name()));
|
|
||||||
|
|
||||||
if (raceLogEvent != null)
|
// query for obsolete events
|
||||||
result.add(raceLogEvent);
|
query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(String.format("%s.%s.%s",
|
||||||
}
|
identifier.getTemplate().getParentObjectName(),
|
||||||
|
identifier.getRaceColumnName(),
|
||||||
|
identifier.getFleetName())));
|
||||||
|
loadRaceLogEvents(result, query);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// something went wrong during DB access; report, then use empty new race log
|
// something went wrong during DB access; report, then use empty new race log
|
||||||
logger.log(Level.SEVERE, "Error connecting to MongoDB, unable to load recorded race log data. Check MongoDB settings.");
|
logger.log(Level.SEVERE, "Error connecting to MongoDB, unable to load recorded race log data. Check MongoDB settings.");
|
||||||
@@ -1022,6 +1023,16 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadRaceLogEvents(RaceLog result, BasicDBObject query) {
|
||||||
|
DBCollection raceLog = database.getCollection(CollectionNames.RACE_LOGS.name());
|
||||||
|
for (DBObject o : raceLog.find(query)) {
|
||||||
|
RaceLogEvent raceLogEvent = loadRaceLogEvent((DBObject) o.get(FieldNames.RACE_LOG_EVENT.name()));
|
||||||
|
if (raceLogEvent != null) {
|
||||||
|
result.add(raceLogEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public RaceLogEvent loadRaceLogEvent(DBObject dbObject) {
|
public RaceLogEvent loadRaceLogEvent(DBObject dbObject) {
|
||||||
TimePoint timePoint = loadTimePoint(dbObject);
|
TimePoint timePoint = loadTimePoint(dbObject);
|
||||||
TimePoint createdAt = loadTimePoint(dbObject, FieldNames.RACE_LOG_EVENT_CREATED_AT);
|
TimePoint createdAt = loadTimePoint(dbObject, FieldNames.RACE_LOG_EVENT_CREATED_AT);
|
||||||
@@ -1190,7 +1201,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
|||||||
|
|
||||||
private CourseBase loadCourseData(BasicDBList dbCourseList, String courseName) {
|
private CourseBase loadCourseData(BasicDBList dbCourseList, String courseName) {
|
||||||
if (courseName == null) {
|
if (courseName == null) {
|
||||||
courseName = "Course template";
|
courseName = "Course";
|
||||||
}
|
}
|
||||||
CourseBase courseData = new CourseDataImpl(courseName);
|
CourseBase courseData = new CourseDataImpl(courseName);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
+13
-13
@@ -536,7 +536,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFlagEvent flagEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFlagEvent flagEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
|
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFlagEvent(flagEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFlagEvent(flagEvent));
|
||||||
return result;
|
return result;
|
||||||
@@ -544,7 +544,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartTimeEvent startTimeEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartTimeEvent startTimeEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
|
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartTimeEvent(startTimeEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartTimeEvent(startTimeEvent));
|
||||||
return result;
|
return result;
|
||||||
@@ -552,7 +552,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogPassChangeEvent passChangeEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogPassChangeEvent passChangeEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
|
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogPassChangeEvent(passChangeEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogPassChangeEvent(passChangeEvent));
|
||||||
return result;
|
return result;
|
||||||
@@ -560,7 +560,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogRaceStatusEvent raceStatusEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogRaceStatusEvent raceStatusEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
|
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogRaceStatusEvent(raceStatusEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogRaceStatusEvent(raceStatusEvent));
|
||||||
return result;
|
return result;
|
||||||
@@ -568,63 +568,63 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogCourseAreaChangedEvent courseAreaChangedEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogCourseAreaChangedEvent courseAreaChangedEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogCourseAreaChangedEvent(courseAreaChangedEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogCourseAreaChangedEvent(courseAreaChangedEvent));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogCourseDesignChangedEvent courseDesignChangedEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogCourseDesignChangedEvent courseDesignChangedEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogCourseDesignChangedEvent(courseDesignChangedEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogCourseDesignChangedEvent(courseDesignChangedEvent));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFinishPositioningListChangedEvent finishPositioningListChangedEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFinishPositioningListChangedEvent finishPositioningListChangedEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFinishPositioningListChangedEvent(finishPositioningListChangedEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFinishPositioningListChangedEvent(finishPositioningListChangedEvent));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFinishPositioningConfirmedEvent finishPositioningConfirmedEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFinishPositioningConfirmedEvent finishPositioningConfirmedEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFinishPositioningConfirmedEvent(finishPositioningConfirmedEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFinishPositioningConfirmedEvent(finishPositioningConfirmedEvent));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogPathfinderEvent pathfinderEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogPathfinderEvent pathfinderEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogPathfinderEvent(pathfinderEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogPathfinderEvent(pathfinderEvent));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogGateLineOpeningTimeEvent gateLineOpeningTimeEvent) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogGateLineOpeningTimeEvent gateLineOpeningTimeEvent) {
|
||||||
BasicDBObject result = new BasicDBObject();
|
BasicDBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogGateLineOpeningTimeEvent(gateLineOpeningTimeEvent));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogGateLineOpeningTimeEvent(gateLineOpeningTimeEvent));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartProcedureChangedEvent event) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartProcedureChangedEvent event) {
|
||||||
DBObject result = new BasicDBObject();
|
DBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartProcedureChangedEvent(event));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartProcedureChangedEvent(event));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogProtestStartTimeEvent event) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogProtestStartTimeEvent event) {
|
||||||
DBObject result = new BasicDBObject();
|
DBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogProtestStartTimeEvent(event));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogProtestStartTimeEvent(event));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogWindFixEvent event) {
|
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogWindFixEvent event) {
|
||||||
DBObject result = new BasicDBObject();
|
DBObject result = new BasicDBObject();
|
||||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogWindFix(event));
|
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogWindFix(event));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package com.sap.sailing.domain.persistence.impl;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||||
|
|
||||||
|
public class TripleSerializer {
|
||||||
|
public static DBObject serialize(Triple<String, String, String> value) {
|
||||||
|
DBObject container = new BasicDBObject();
|
||||||
|
container.put("a", value.getA());
|
||||||
|
container.put("b", value.getB());
|
||||||
|
container.put("c", value.getC());
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -831,4 +831,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimePoint getStartTimeReceived() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -539,4 +539,10 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimePoint getStartTimeReceived() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
@@ -11,5 +11,6 @@ public interface TracTracConnectionConstants {
|
|||||||
final int PORT_STORED = PORT_LIVE + 1; //For official usage use 4401;
|
final int PORT_STORED = PORT_LIVE + 1; //For official usage use 4401;
|
||||||
|
|
||||||
final String HIDDEN_STATUS = "HIDDEN";
|
final String HIDDEN_STATUS = "HIDDEN";
|
||||||
|
final Object REPLAY_STATUS = "REPLAY";
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
@@ -41,6 +41,7 @@ public class TracTracCourseDesignUpdateHandler extends UpdateHandler implements
|
|||||||
@Override
|
@Override
|
||||||
public void courseDesignChanged(CourseBase newCourseDesign) throws MalformedURLException, IOException {
|
public void courseDesignChanged(CourseBase newCourseDesign) throws MalformedURLException, IOException {
|
||||||
if (!isActive()) {
|
if (!isActive()) {
|
||||||
|
logger.info("Not sending course update to TracTrac because no URL has been provided.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-2
@@ -582,14 +582,29 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
updateStatusOfTrackedRaces();
|
updateStatusOfTrackedRaces();
|
||||||
} else {
|
} else {
|
||||||
// ask RacingEventService to cleanly stop and unregister this tracker
|
// ask RacingEventService to cleanly stop and unregister this tracker
|
||||||
for (RaceDefinition race : getRaces()) {
|
// if the race has all data loaded. Doing this asynchronously because
|
||||||
|
// stopping can take longer and if you're loading many races in parallel
|
||||||
|
// this can slow down loading extremely
|
||||||
|
for (final RaceDefinition race : getRaces()) {
|
||||||
|
DynamicTrackedRace trackedRace = getTrackedRegatta().getExistingTrackedRace(race);
|
||||||
|
final Regatta regatta = getRegatta();
|
||||||
|
if (trackedRace.getStatus().getLoadingProgress() == 1.0) {
|
||||||
|
Thread raceStopper = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
try {
|
try {
|
||||||
trackedRegattaRegistry.stopTracking(getRegatta(), race);
|
trackedRegattaRegistry.stopTracking(regatta, race);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, "Error trying to stop tracker for race "+race.getName()+
|
logger.log(Level.SEVERE, "Error trying to stop tracker for race "+race.getName()+
|
||||||
" in regatta "+getRegatta().getName(), e);
|
" in regatta "+getRegatta().getName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
raceStopper.start();
|
||||||
|
} else {
|
||||||
|
logger.log(Level.SEVERE, "Not stopping race "+race.getName()+" because it has not all data loaded! Progress: " + trackedRace.getStatus().getLoadingProgress());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -2,13 +2,15 @@ package com.sap.sailing.domain.racelog;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||||
|
|
||||||
public interface RaceLogIdentifier extends Serializable {
|
public interface RaceLogIdentifier extends Serializable {
|
||||||
|
|
||||||
String getRaceColumnName();
|
String getRaceColumnName();
|
||||||
|
|
||||||
String getFleetName();
|
String getFleetName();
|
||||||
|
|
||||||
Serializable getIdentifier();
|
Triple<String, String, String> getIdentifier();
|
||||||
|
|
||||||
RaceLogIdentifierTemplate getTemplate();
|
RaceLogIdentifierTemplate getTemplate();
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
package com.sap.sailing.domain.racelog.impl;
|
package com.sap.sailing.domain.racelog.impl;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.Fleet;
|
import com.sap.sailing.domain.base.Fleet;
|
||||||
|
import com.sap.sailing.domain.common.impl.Util;
|
||||||
|
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogIdentifierTemplate;
|
import com.sap.sailing.domain.racelog.RaceLogIdentifierTemplate;
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@ public class RaceLogIdentifierImpl implements RaceLogIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Serializable getIdentifier() {
|
public Triple<String, String, String> getIdentifier() {
|
||||||
return String.format("%s.%s.%s", template.getParentObjectName(), raceColumnName, fleetName);
|
return new Util.Triple<String, String, String>(template.getParentObjectName(), raceColumnName, fleetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -575,4 +575,9 @@ public interface TrackedRace extends Serializable {
|
|||||||
* If the competitor hasn't started yet, <code>null</code> is returned.
|
* If the competitor hasn't started yet, <code>null</code> is returned.
|
||||||
*/
|
*/
|
||||||
Distance getDistanceFromStarboardSideOfStartLineWhenPassingStart(Competitor competitor);
|
Distance getDistanceFromStarboardSideOfStartLineWhenPassingStart(Competitor competitor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start time received by the tracking infrastructure. To determine real start time use {@link #getStartOfRace()}.
|
||||||
|
*/
|
||||||
|
TimePoint getStartTimeReceived();
|
||||||
}
|
}
|
||||||
+25
-5
@@ -1,6 +1,9 @@
|
|||||||
package com.sap.sailing.domain.tracking.impl;
|
package com.sap.sailing.domain.tracking.impl;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.CourseBase;
|
import com.sap.sailing.domain.base.CourseBase;
|
||||||
|
import com.sap.sailing.domain.common.TimePoint;
|
||||||
import com.sap.sailing.domain.common.WindSource;
|
import com.sap.sailing.domain.common.WindSource;
|
||||||
import com.sap.sailing.domain.common.WindSourceType;
|
import com.sap.sailing.domain.common.WindSourceType;
|
||||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||||
@@ -21,19 +24,22 @@ import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
|
|||||||
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
|
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
|
||||||
import com.sap.sailing.domain.racelog.analyzing.impl.LastPublishedCourseDesignFinder;
|
import com.sap.sailing.domain.racelog.analyzing.impl.LastPublishedCourseDesignFinder;
|
||||||
import com.sap.sailing.domain.racelog.analyzing.impl.RaceStatusAnalyzer;
|
import com.sap.sailing.domain.racelog.analyzing.impl.RaceStatusAnalyzer;
|
||||||
|
import com.sap.sailing.domain.racelog.analyzing.impl.StartTimeFinder;
|
||||||
import com.sap.sailing.domain.racelog.analyzing.impl.WindFixesFinder;
|
import com.sap.sailing.domain.racelog.analyzing.impl.WindFixesFinder;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.Wind;
|
import com.sap.sailing.domain.tracking.Wind;
|
||||||
|
|
||||||
public class DynamicTrackedRaceLogListener implements RaceLogEventVisitor {
|
public class DynamicTrackedRaceLogListener implements RaceLogEventVisitor {
|
||||||
|
|
||||||
|
public static final Logger log = Logger.getLogger(DynamicTrackedRaceLogListener.class.getName());
|
||||||
|
|
||||||
private DynamicTrackedRace trackedRace;
|
private DynamicTrackedRace trackedRace;
|
||||||
|
|
||||||
private final WindSource raceCommitteeWindSource;
|
private final WindSource raceCommitteeWindSource;
|
||||||
|
|
||||||
private RaceStatusAnalyzer statusAnalyzer;
|
private RaceStatusAnalyzer statusAnalyzer;
|
||||||
|
|
||||||
private LastPublishedCourseDesignFinder courseDesignFinder;
|
private LastPublishedCourseDesignFinder courseDesignFinder;
|
||||||
|
private StartTimeFinder startTimeFinder;
|
||||||
|
|
||||||
public DynamicTrackedRaceLogListener(DynamicTrackedRace trackedRace) {
|
public DynamicTrackedRaceLogListener(DynamicTrackedRace trackedRace) {
|
||||||
this.trackedRace = trackedRace;
|
this.trackedRace = trackedRace;
|
||||||
@@ -105,20 +111,34 @@ public class DynamicTrackedRaceLogListener implements RaceLogEventVisitor {
|
|||||||
// Because this code can be triggered by an obsolete (delayed) event...
|
// Because this code can be triggered by an obsolete (delayed) event...
|
||||||
// ... onCourseDesignChangedByRaceCommittee() might be called more than once.
|
// ... onCourseDesignChangedByRaceCommittee() might be called more than once.
|
||||||
trackedRace.onCourseDesignChangedByRaceCommittee(courseDesign);
|
trackedRace.onCourseDesignChangedByRaceCommittee(courseDesign);
|
||||||
|
} else {
|
||||||
|
log.info("Could not find any course design update on race log of " + trackedRace.getRace().getName() + "! Not sending out any events.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void analyzeStartTime() {
|
||||||
|
/* start time will be set by StartTimeAnalyzer in TrackedRace.getStartTime() */
|
||||||
|
trackedRace.invalidateStartTime();
|
||||||
|
|
||||||
|
TimePoint startTime = startTimeFinder.analyze();
|
||||||
|
if (startTime != null) {
|
||||||
|
/* invoke listeners with received start time, this will also trigger tractrac update */
|
||||||
|
trackedRace.onStartTimeChangedByRaceCommittee(startTime);
|
||||||
|
} else {
|
||||||
|
log.info("Could not find any valid start time on race log of " + trackedRace.getRace().getName() + "! Not sending out any events.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RaceLogPassChangeEvent event) {
|
public void visit(RaceLogPassChangeEvent event) {
|
||||||
trackedRace.invalidateStartTime();
|
trackedRace.invalidateStartTime();
|
||||||
|
/* this will send tractrac the original start time */
|
||||||
|
trackedRace.onStartTimeChangedByRaceCommittee(trackedRace.getStartTimeReceived());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RaceLogStartTimeEvent event) {
|
public void visit(RaceLogStartTimeEvent event) {
|
||||||
/* start time will be set by StartTimeAnalyzer in TrackedRace.getStartTime() */
|
analyzeStartTime();
|
||||||
trackedRace.invalidateStartTime();
|
|
||||||
/* invoke listeners with received start time, this will also trigger tractrac update */
|
|
||||||
trackedRace.onStartTimeChangedByRaceCommittee(event.getStartTime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -495,7 +495,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (startTime == null) {
|
if (startTime == null) {
|
||||||
startTime = startTimeReceived;
|
startTime = getStartTimeReceived();
|
||||||
// If not null, check if the first mark passing for the start line is too much after the
|
// If not null, check if the first mark passing for the start line is too much after the
|
||||||
// startTimeReceived; if so, return an adjusted, later start time.
|
// startTimeReceived; if so, return an adjusted, later start time.
|
||||||
// If no official start time was received, try to estimate the start time using the mark passings for
|
// If no official start time was received, try to estimate the start time using the mark passings for
|
||||||
@@ -1356,7 +1356,8 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TimePoint getStartTimeReceived() {
|
@Override
|
||||||
|
public TimePoint getStartTimeReceived() {
|
||||||
return startTimeReceived;
|
return startTimeReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -833,4 +833,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimePoint getStartTimeReceived() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -706,3 +706,8 @@ video {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pointeredLink {
|
||||||
|
cursor: pointer;
|
||||||
|
cursor: hand;
|
||||||
|
}
|
||||||
+97
-21
@@ -1,6 +1,8 @@
|
|||||||
package com.sap.sailing.gwt.ui.masterdataimport;
|
package com.sap.sailing.gwt.ui.masterdataimport;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
import com.google.gwt.event.dom.client.ClickEvent;
|
||||||
@@ -8,6 +10,8 @@ import com.google.gwt.event.dom.client.ClickHandler;
|
|||||||
import com.google.gwt.event.dom.client.KeyCodes;
|
import com.google.gwt.event.dom.client.KeyCodes;
|
||||||
import com.google.gwt.event.dom.client.KeyDownEvent;
|
import com.google.gwt.event.dom.client.KeyDownEvent;
|
||||||
import com.google.gwt.event.dom.client.KeyDownHandler;
|
import com.google.gwt.event.dom.client.KeyDownHandler;
|
||||||
|
import com.google.gwt.event.dom.client.KeyUpEvent;
|
||||||
|
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||||
import com.google.gwt.http.client.Request;
|
import com.google.gwt.http.client.Request;
|
||||||
import com.google.gwt.http.client.RequestBuilder;
|
import com.google.gwt.http.client.RequestBuilder;
|
||||||
import com.google.gwt.http.client.RequestCallback;
|
import com.google.gwt.http.client.RequestCallback;
|
||||||
@@ -15,7 +19,6 @@ import com.google.gwt.http.client.RequestException;
|
|||||||
import com.google.gwt.http.client.Response;
|
import com.google.gwt.http.client.Response;
|
||||||
import com.google.gwt.json.client.JSONArray;
|
import com.google.gwt.json.client.JSONArray;
|
||||||
import com.google.gwt.json.client.JSONParser;
|
import com.google.gwt.json.client.JSONParser;
|
||||||
import com.google.gwt.json.client.JSONString;
|
|
||||||
import com.google.gwt.regexp.shared.RegExp;
|
import com.google.gwt.regexp.shared.RegExp;
|
||||||
import com.google.gwt.user.client.Window;
|
import com.google.gwt.user.client.Window;
|
||||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
@@ -41,6 +44,8 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
private Button importLeaderboardGroupsButton;
|
private Button importLeaderboardGroupsButton;
|
||||||
private Button fetchIdsButton;
|
private Button fetchIdsButton;
|
||||||
|
|
||||||
|
private List<String> allLeaderboardGroupNames;
|
||||||
|
|
||||||
private RegExp urlValidator;
|
private RegExp urlValidator;
|
||||||
private RegExp urlPlusTldValidator;
|
private RegExp urlPlusTldValidator;
|
||||||
|
|
||||||
@@ -113,7 +118,7 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
protected void importLeaderboardGroups() {
|
protected void importLeaderboardGroups() {
|
||||||
String[] groupNames = createLeaderBoardGroupNamesFromListBox();
|
String[] groupNames = createLeaderBoardGroupNamesFromListBox();
|
||||||
if (groupNames.length >= 1) {
|
if (groupNames.length >= 1) {
|
||||||
changeAllButtonState(false);
|
disableAllButtons();
|
||||||
boolean override = overrideSwitch.getValue();
|
boolean override = overrideSwitch.getValue();
|
||||||
sailingService.importMasterData(currentHost, groupNames, override,
|
sailingService.importMasterData(currentHost, groupNames, override,
|
||||||
new AsyncCallback<MasterDataImportObjectCreationCount>() {
|
new AsyncCallback<MasterDataImportObjectCreationCount>() {
|
||||||
@@ -135,13 +140,13 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
}
|
}
|
||||||
showSuccessAlert(leaderboardsCreated, leaderboardGroupsCreated, eventsCreated,
|
showSuccessAlert(leaderboardsCreated, leaderboardGroupsCreated, eventsCreated,
|
||||||
regattasCreated);
|
regattasCreated);
|
||||||
changeAllButtonState(true);
|
changeButtonStateAccordingToApplicationState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable caught) {
|
public void onFailure(Throwable caught) {
|
||||||
showErrorAlert(caught.getLocalizedMessage());
|
showErrorAlert(caught.getLocalizedMessage());
|
||||||
changeAllButtonState(true);
|
changeButtonStateAccordingToApplicationState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -150,12 +155,34 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void changeAllButtonState(boolean enabled) {
|
private void disableAllButtons() {
|
||||||
|
boolean enabled = false;
|
||||||
importLeaderboardGroupsButton.setEnabled(enabled);
|
importLeaderboardGroupsButton.setEnabled(enabled);
|
||||||
overrideSwitch.setEnabled(enabled);
|
overrideSwitch.setEnabled(enabled);
|
||||||
fetchIdsButton.setEnabled(enabled);
|
fetchIdsButton.setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void changeButtonStateAccordingToApplicationState() {
|
||||||
|
if (leaderboardgroupListBox.getItemCount() > 0 && countSelectedItems() > 0) {
|
||||||
|
importLeaderboardGroupsButton.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
importLeaderboardGroupsButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
overrideSwitch.setEnabled(true);
|
||||||
|
fetchIdsButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int countSelectedItems() {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < leaderboardgroupListBox.getItemCount(); i++) {
|
||||||
|
if (leaderboardgroupListBox.isItemSelected(i)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
protected void showSuccessAlert(int leaderboardsCreated, int leaderboardGroupsCreated, int eventsCreated,
|
protected void showSuccessAlert(int leaderboardsCreated, int leaderboardGroupsCreated, int eventsCreated,
|
||||||
int regattasCreated) {
|
int regattasCreated) {
|
||||||
Window.alert(stringMessages.importSuccess(leaderboardGroupsCreated, leaderboardsCreated, eventsCreated,
|
Window.alert(stringMessages.importSuccess(leaderboardGroupsCreated, leaderboardsCreated, eventsCreated,
|
||||||
@@ -187,7 +214,7 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
showErrorAlert(stringMessages.importUrlInvalid(getLgsUrl));
|
showErrorAlert(stringMessages.importUrlInvalid(getLgsUrl));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
changeAllButtonState(false);
|
disableAllButtons();
|
||||||
RequestBuilder getLgsRequestBuilder = new RequestBuilder(RequestBuilder.GET, getLgsUrl);
|
RequestBuilder getLgsRequestBuilder = new RequestBuilder(RequestBuilder.GET, getLgsUrl);
|
||||||
getLgsRequestBuilder.setCallback(new RequestCallback() {
|
getLgsRequestBuilder.setCallback(new RequestCallback() {
|
||||||
|
|
||||||
@@ -196,41 +223,38 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
if (response.getStatusCode() != 200) {
|
if (response.getStatusCode() != 200) {
|
||||||
showErrorAlert(stringMessages.importGetLeaderboardsFailed(response.getStatusCode(), getLgsUrl));
|
showErrorAlert(stringMessages.importGetLeaderboardsFailed(response.getStatusCode(), getLgsUrl));
|
||||||
}
|
}
|
||||||
int itemCount = leaderboardgroupListBox.getItemCount();
|
clearListBox();
|
||||||
for (int i = itemCount - 1; i >= 0; i--) {
|
|
||||||
leaderboardgroupListBox.removeItem(i);
|
|
||||||
}
|
|
||||||
String body = response.getText();
|
String body = response.getText();
|
||||||
if (body == null || body.isEmpty()) {
|
if (body == null || body.isEmpty()) {
|
||||||
showErrorAlert(stringMessages.importNoDataReturned());
|
showErrorAlert(stringMessages.importNoDataReturned());
|
||||||
changeAllButtonState(true);
|
changeButtonStateAccordingToApplicationState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JSONArray leaderboardGroups = JSONParser.parseStrict(body).isArray();
|
JSONArray leaderboardGroups = JSONParser.parseStrict(body).isArray();
|
||||||
leaderboardgroupListBox.setVisibleItemCount(leaderboardGroups.size());
|
List<String> toSort = new ArrayList<String>();
|
||||||
for (int i = 0; i < leaderboardGroups.size(); i++) {
|
for (int i = 0; i < leaderboardGroups.size(); i++) {
|
||||||
JSONString leaderboardGroupName = leaderboardGroups.get(i).isString();
|
toSort.add(leaderboardGroups.get(i).isString().stringValue());
|
||||||
leaderboardgroupListBox.addItem(leaderboardGroupName.stringValue());
|
|
||||||
}
|
}
|
||||||
if (leaderboardGroups.size() > 1) {
|
Collections.sort(toSort);
|
||||||
importLeaderboardGroupsButton.setEnabled(true);
|
allLeaderboardGroupNames = toSort;
|
||||||
} else {
|
leaderboardgroupListBox.setVisibleItemCount(leaderboardGroups.size());
|
||||||
importLeaderboardGroupsButton.setEnabled(false);
|
for (String lgName : toSort) {
|
||||||
|
leaderboardgroupListBox.addItem(lgName);
|
||||||
}
|
}
|
||||||
changeAllButtonState(true);
|
changeButtonStateAccordingToApplicationState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Request request, Throwable exception) {
|
public void onError(Request request, Throwable exception) {
|
||||||
showErrorAlert(stringMessages.importServerError());
|
showErrorAlert(stringMessages.importServerError());
|
||||||
changeAllButtonState(true);
|
changeButtonStateAccordingToApplicationState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
getLgsRequestBuilder.send();
|
getLgsRequestBuilder.send();
|
||||||
} catch (RequestException e) {
|
} catch (RequestException e) {
|
||||||
showErrorAlert(stringMessages.importServerError());
|
showErrorAlert(stringMessages.importServerError());
|
||||||
changeAllButtonState(true);
|
changeButtonStateAccordingToApplicationState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +291,15 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
private void addContentToLeftPanel(VerticalPanel contentPanel) {
|
private void addContentToLeftPanel(VerticalPanel contentPanel) {
|
||||||
contentPanel.add(new Label(stringMessages.importLeaderboardGroups()));
|
contentPanel.add(new Label(stringMessages.importLeaderboardGroups()));
|
||||||
|
|
||||||
|
HorizontalPanel filterPanel = new HorizontalPanel();
|
||||||
|
filterPanel.add(new Label(stringMessages.filterName() + ":"));
|
||||||
|
TextBox filterBox = new TextBox();
|
||||||
|
setFilterHandler(filterBox);
|
||||||
|
filterPanel.add(filterBox);
|
||||||
|
contentPanel.add(filterPanel);
|
||||||
|
|
||||||
leaderboardgroupListBox = new ListBox(true);
|
leaderboardgroupListBox = new ListBox(true);
|
||||||
|
addSelectionChangedListener();
|
||||||
contentPanel.add(leaderboardgroupListBox);
|
contentPanel.add(leaderboardgroupListBox);
|
||||||
|
|
||||||
overrideSwitch = new CheckBox(stringMessages.importOverrideSwitchLabel());
|
overrideSwitch = new CheckBox(stringMessages.importOverrideSwitchLabel());
|
||||||
@@ -279,4 +311,48 @@ public class MasterDataImportPanel extends VerticalPanel {
|
|||||||
contentPanel.add(importLeaderboardGroupsButton);
|
contentPanel.add(importLeaderboardGroupsButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addSelectionChangedListener() {
|
||||||
|
leaderboardgroupListBox.addClickHandler(new ClickHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(ClickEvent event) {
|
||||||
|
changeButtonStateAccordingToApplicationState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFilterHandler(final TextBox filterBox) {
|
||||||
|
filterBox.addKeyUpHandler(new KeyUpHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onKeyUp(KeyUpEvent event) {
|
||||||
|
clearListBox();
|
||||||
|
int visibleNameCount = 0;
|
||||||
|
List<String> filterTexts = Arrays.asList(filterBox.getText().split(" "));
|
||||||
|
for(String name : allLeaderboardGroupNames) {
|
||||||
|
boolean containsAllFilterTexts = true;
|
||||||
|
for (String filterText : filterTexts) {
|
||||||
|
if (!name.toUpperCase().contains(filterText.toUpperCase())) {
|
||||||
|
containsAllFilterTexts = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (containsAllFilterTexts) {
|
||||||
|
leaderboardgroupListBox.addItem(name);
|
||||||
|
visibleNameCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
leaderboardgroupListBox.setVisibleItemCount(visibleNameCount);
|
||||||
|
changeButtonStateAccordingToApplicationState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearListBox() {
|
||||||
|
int itemCount = leaderboardgroupListBox.getItemCount();
|
||||||
|
for (int i = itemCount - 1; i >= 0; i--) {
|
||||||
|
leaderboardgroupListBox.removeItem(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+27
-24
@@ -9,11 +9,9 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.gwt.cell.client.ClickableTextCell;
|
|
||||||
import com.google.gwt.cell.client.FieldUpdater;
|
import com.google.gwt.cell.client.FieldUpdater;
|
||||||
import com.google.gwt.cell.client.SafeHtmlCell;
|
import com.google.gwt.cell.client.SafeHtmlCell;
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
import com.google.gwt.dom.client.BrowserEvents;
|
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
import com.google.gwt.event.dom.client.ClickEvent;
|
||||||
import com.google.gwt.event.dom.client.ClickHandler;
|
import com.google.gwt.event.dom.client.ClickHandler;
|
||||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||||
@@ -38,8 +36,6 @@ import com.google.gwt.user.client.ui.Label;
|
|||||||
import com.google.gwt.user.client.ui.SimplePanel;
|
import com.google.gwt.user.client.ui.SimplePanel;
|
||||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||||
import com.google.gwt.user.client.ui.Widget;
|
import com.google.gwt.user.client.ui.Widget;
|
||||||
import com.google.gwt.view.client.CellPreviewEvent;
|
|
||||||
import com.google.gwt.view.client.CellPreviewEvent.Handler;
|
|
||||||
import com.google.gwt.view.client.ListDataProvider;
|
import com.google.gwt.view.client.ListDataProvider;
|
||||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||||
import com.sap.sailing.domain.common.NauticalSide;
|
import com.sap.sailing.domain.common.NauticalSide;
|
||||||
@@ -57,6 +53,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
|||||||
import com.sap.sailing.gwt.ui.client.Timer;
|
import com.sap.sailing.gwt.ui.client.Timer;
|
||||||
import com.sap.sailing.gwt.ui.client.shared.components.Component;
|
import com.sap.sailing.gwt.ui.client.shared.components.Component;
|
||||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
|
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
|
||||||
|
import com.sap.sailing.gwt.ui.shared.ClickableSafeHtmlCell;
|
||||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||||
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
|
||||||
@@ -145,14 +142,6 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
|||||||
|
|
||||||
regattaOverviewDataProvider = new ListDataProvider<RegattaOverviewEntryDTO>();
|
regattaOverviewDataProvider = new ListDataProvider<RegattaOverviewEntryDTO>();
|
||||||
regattaOverviewTable = createRegattaTable();
|
regattaOverviewTable = createRegattaTable();
|
||||||
regattaOverviewTable.addCellPreviewHandler(new Handler<RegattaOverviewEntryDTO>() {
|
|
||||||
@Override
|
|
||||||
public void onCellPreview(CellPreviewEvent<RegattaOverviewEntryDTO> event) {
|
|
||||||
if (BrowserEvents.CLICK.equals(event.getNativeEvent().getType()) && entryClickedHandler != null){
|
|
||||||
entryClickedHandler.onEntryClicked(event.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mainPanel.add(regattaOverviewTable);
|
mainPanel.add(regattaOverviewTable);
|
||||||
setWidget(mainPanel);
|
setWidget(mainPanel);
|
||||||
@@ -379,13 +368,24 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
TextColumn<RegattaOverviewEntryDTO> raceStatusColumn = new TextColumn<RegattaOverviewEntryDTO>() {
|
Column<RegattaOverviewEntryDTO, SafeHtml> raceStatusColumn = new Column<RegattaOverviewEntryDTO, SafeHtml>(new ClickableSafeHtmlCell()) {
|
||||||
@Override
|
@Override
|
||||||
public String getValue(RegattaOverviewEntryDTO entryDTO) {
|
public SafeHtml getValue(final RegattaOverviewEntryDTO entryDTO) {
|
||||||
return flagInterpreter.getMeaningOfRaceStateAndFlags(entryDTO.raceInfo.lastStatus, entryDTO.raceInfo.lastUpperFlag,
|
String status = flagInterpreter.getMeaningOfRaceStateAndFlags(entryDTO.raceInfo.lastStatus, entryDTO.raceInfo.lastUpperFlag,
|
||||||
entryDTO.raceInfo.lastLowerFlag, entryDTO.raceInfo.isLastFlagDisplayed);
|
entryDTO.raceInfo.lastLowerFlag, entryDTO.raceInfo.isLastFlagDisplayed);
|
||||||
|
SafeHtmlBuilder sb = new SafeHtmlBuilder();
|
||||||
|
sb.appendHtmlConstant("<a class=\"pointeredLink\">");
|
||||||
|
sb.appendEscaped(status);
|
||||||
|
sb.appendHtmlConstant("</a>");
|
||||||
|
return sb.toSafeHtml();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
raceStatusColumn.setFieldUpdater(new FieldUpdater<RegattaOverviewEntryDTO, SafeHtml>() {
|
||||||
|
@Override
|
||||||
|
public void update(int index, RegattaOverviewEntryDTO object, SafeHtml value) {
|
||||||
|
entryClickedHandler.onEntryClicked(object);
|
||||||
|
}
|
||||||
|
});
|
||||||
raceStatusColumn.setSortable(true);
|
raceStatusColumn.setSortable(true);
|
||||||
regattaOverviewListHandler.setComparator(raceStatusColumn, new Comparator<RegattaOverviewEntryDTO>() {
|
regattaOverviewListHandler.setComparator(raceStatusColumn, new Comparator<RegattaOverviewEntryDTO>() {
|
||||||
|
|
||||||
@@ -397,20 +397,24 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
|||||||
});
|
});
|
||||||
raceStatusColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
raceStatusColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||||
|
|
||||||
Column<RegattaOverviewEntryDTO, String> raceCourseColumn = new Column<RegattaOverviewEntryDTO, String>(new ClickableTextCell()) {
|
Column<RegattaOverviewEntryDTO, SafeHtml> raceCourseColumn = new Column<RegattaOverviewEntryDTO, SafeHtml>(new ClickableSafeHtmlCell()) {
|
||||||
@Override
|
@Override
|
||||||
public String getValue(RegattaOverviewEntryDTO entryDTO) {
|
public SafeHtml getValue(final RegattaOverviewEntryDTO entryDTO) {
|
||||||
String courseName = "-";
|
SafeHtmlBuilder sb = new SafeHtmlBuilder();
|
||||||
if (entryDTO.raceInfo.lastCourseName != null) {
|
if (entryDTO.raceInfo.lastCourseName != null) {
|
||||||
courseName = entryDTO.raceInfo.lastCourseName;
|
String courseName = entryDTO.raceInfo.lastCourseName;
|
||||||
|
sb.appendHtmlConstant("<a class=\"pointeredLink\">");
|
||||||
|
sb.appendEscaped(courseName);
|
||||||
|
sb.appendHtmlConstant("</a>");
|
||||||
|
return sb.toSafeHtml();
|
||||||
|
} else {
|
||||||
|
return sb.toSafeHtml();
|
||||||
}
|
}
|
||||||
return courseName;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
raceCourseColumn.setFieldUpdater(new FieldUpdater<RegattaOverviewEntryDTO, String>() {
|
raceCourseColumn.setFieldUpdater(new FieldUpdater<RegattaOverviewEntryDTO, SafeHtml>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(int index, RegattaOverviewEntryDTO object, String value) {
|
public void update(int index, RegattaOverviewEntryDTO object, SafeHtml value) {
|
||||||
if (object.raceInfo.lastCourseDesign.waypoints.size() > 0) {
|
if (object.raceInfo.lastCourseDesign.waypoints.size() > 0) {
|
||||||
DialogBox courseViewDialogBox = createCourseViewDialogBox(object.raceInfo);
|
DialogBox courseViewDialogBox = createCourseViewDialogBox(object.raceInfo);
|
||||||
courseViewDialogBox.center();
|
courseViewDialogBox.center();
|
||||||
@@ -419,7 +423,6 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
|
|||||||
courseViewDialogBox.show();
|
courseViewDialogBox.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
raceCourseColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
raceCourseColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -94,12 +94,12 @@ import com.sap.sailing.domain.common.RegattaIdentifier;
|
|||||||
import com.sap.sailing.domain.common.RegattaName;
|
import com.sap.sailing.domain.common.RegattaName;
|
||||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||||
import com.sap.sailing.domain.common.RegattaScoreCorrections;
|
import com.sap.sailing.domain.common.RegattaScoreCorrections;
|
||||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
|
||||||
import com.sap.sailing.domain.common.RegattaScoreCorrections.ScoreCorrectionForCompetitorInRace;
|
import com.sap.sailing.domain.common.RegattaScoreCorrections.ScoreCorrectionForCompetitorInRace;
|
||||||
import com.sap.sailing.domain.common.RegattaScoreCorrections.ScoreCorrectionsForRace;
|
import com.sap.sailing.domain.common.RegattaScoreCorrections.ScoreCorrectionsForRace;
|
||||||
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
||||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||||
import com.sap.sailing.domain.common.Speed;
|
import com.sap.sailing.domain.common.Speed;
|
||||||
|
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||||
import com.sap.sailing.domain.common.Tack;
|
import com.sap.sailing.domain.common.Tack;
|
||||||
import com.sap.sailing.domain.common.TimePoint;
|
import com.sap.sailing.domain.common.TimePoint;
|
||||||
import com.sap.sailing.domain.common.WindSource;
|
import com.sap.sailing.domain.common.WindSource;
|
||||||
@@ -811,11 +811,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
logger.info("Loaded race " + record.getName() + " in " + record.getEventName() + " start:" + record.getRaceStartTime() + " trackingStart:" + record.getTrackingStartTime() + " trackingEnd:" + record.getTrackingEndTime());
|
logger.info("Loaded race " + record.getName() + " in " + record.getEventName() + " start:" + record.getRaceStartTime() + " trackingStart:" + record.getTrackingStartTime() + " trackingEnd:" + record.getTrackingEndTime());
|
||||||
// note that the live URI may be null for races that were put into replay mode
|
// note that the live URI may be null for races that were put into replay mode
|
||||||
final String effectiveLiveURI;
|
final String effectiveLiveURI;
|
||||||
|
if (!record.getRaceStatus().equals(TracTracConnectionConstants.REPLAY_STATUS)) {
|
||||||
if (liveURI == null || liveURI.trim().length() == 0) {
|
if (liveURI == null || liveURI.trim().length() == 0) {
|
||||||
effectiveLiveURI = record.getLiveURI() == null ? null : record.getLiveURI().toString();
|
effectiveLiveURI = record.getLiveURI() == null ? null : record.getLiveURI().toString();
|
||||||
} else {
|
} else {
|
||||||
effectiveLiveURI = liveURI;
|
effectiveLiveURI = liveURI;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
effectiveLiveURI = null;
|
||||||
|
}
|
||||||
final String effectiveStoredURI;
|
final String effectiveStoredURI;
|
||||||
if (storedURI == null || storedURI.trim().length() == 0) {
|
if (storedURI == null || storedURI.trim().length() == 0) {
|
||||||
effectiveStoredURI = record.getStoredURI().toString();
|
effectiveStoredURI = record.getStoredURI().toString();
|
||||||
|
|||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
package com.sap.sailing.gwt.ui.shared;
|
||||||
|
|
||||||
|
import com.google.gwt.cell.client.AbstractCell;
|
||||||
|
import com.google.gwt.cell.client.ValueUpdater;
|
||||||
|
import com.google.gwt.dom.client.Element;
|
||||||
|
import com.google.gwt.dom.client.NativeEvent;
|
||||||
|
import com.google.gwt.safehtml.shared.SafeHtml;
|
||||||
|
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cell that is clickable and renders its contents as HTML.
|
||||||
|
* Especially useful if you want to render a ClickableTextCell
|
||||||
|
* in a CellTable as an anchor.
|
||||||
|
*
|
||||||
|
* Use it like this:
|
||||||
|
* <pre>
|
||||||
|
* Column<RegattaOverviewEntryDTO, SafeHtml> raceStatusColumn = new Column<RegattaOverviewEntryDTO, SafeHtml>(new ClickableSafeHtmlCell()) {
|
||||||
|
* @Override
|
||||||
|
* public SafeHtml getValue(final RegattaOverviewEntryDTO entryDTO) {
|
||||||
|
* String status = "my string";
|
||||||
|
* SafeHtmlBuilder sb = new SafeHtmlBuilder();
|
||||||
|
* sb.appendHtmlConstant("<a>");
|
||||||
|
* sb.appendEscaped(status);
|
||||||
|
* sb.appendHtmlConstant("</a>");
|
||||||
|
* return sb.toSafeHtml();
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Simon Pamies
|
||||||
|
*/
|
||||||
|
public class ClickableSafeHtmlCell extends AbstractCell<SafeHtml> {
|
||||||
|
|
||||||
|
public ClickableSafeHtmlCell() {
|
||||||
|
super("click", "keydown");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBrowserEvent(Context context, Element parent, SafeHtml value, NativeEvent event,
|
||||||
|
ValueUpdater<SafeHtml> valueUpdater) {
|
||||||
|
super.onBrowserEvent(context, parent, value, event, valueUpdater);
|
||||||
|
if ("click".equals(event.getType())) {
|
||||||
|
onEnterKeyDown(context, parent, value, event, valueUpdater);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEnterKeyDown(Context context, Element parent, SafeHtml value,
|
||||||
|
NativeEvent event, ValueUpdater<SafeHtml> valueUpdater) {
|
||||||
|
if (valueUpdater != null) {
|
||||||
|
valueUpdater.update(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
|
||||||
|
if (value != null) {
|
||||||
|
sb.append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-1
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.base.Competitor;
|
|||||||
import com.sap.sailing.domain.common.TimePoint;
|
import com.sap.sailing.domain.common.TimePoint;
|
||||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||||
import com.sap.sailing.domain.common.impl.Util;
|
import com.sap.sailing.domain.common.impl.Util;
|
||||||
|
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||||
import com.sap.sailing.domain.common.racelog.Flags;
|
import com.sap.sailing.domain.common.racelog.Flags;
|
||||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||||
import com.sap.sailing.domain.persistence.MongoFactory;
|
import com.sap.sailing.domain.persistence.MongoFactory;
|
||||||
@@ -58,7 +59,7 @@ public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
logIdentifier = mock(RaceLogIdentifier.class);
|
logIdentifier = mock(RaceLogIdentifier.class);
|
||||||
when(logIdentifier.getIdentifier()).thenReturn(UUID.randomUUID());
|
when(logIdentifier.getIdentifier()).thenReturn(new Triple<String, String, String>("a", "b", UUID.randomUUID().toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertBaseFields(RaceLogEvent expectedEvent, RaceLogEvent actualEvent) {
|
public void assertBaseFields(RaceLogEvent expectedEvent, RaceLogEvent actualEvent) {
|
||||||
|
|||||||
+152
@@ -0,0 +1,152 @@
|
|||||||
|
package com.sap.sailing.mongodb.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
import com.mongodb.MongoException;
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.base.Fleet;
|
||||||
|
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||||
|
import com.sap.sailing.domain.common.impl.Util;
|
||||||
|
import com.sap.sailing.domain.common.racelog.Flags;
|
||||||
|
import com.sap.sailing.domain.persistence.MongoFactory;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||||
|
import com.sap.sailing.domain.racelog.RaceLog;
|
||||||
|
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
|
||||||
|
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
|
||||||
|
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelog.RaceLogIdentifierTemplate;
|
||||||
|
import com.sap.sailing.domain.racelog.impl.RaceLogIdentifierImpl;
|
||||||
|
|
||||||
|
public class StoreAndLoadRaceLogsTest extends AbstractMongoDBTest {
|
||||||
|
|
||||||
|
protected MongoObjectFactoryImpl mongoFactory = (MongoObjectFactoryImpl) MongoFactory.INSTANCE
|
||||||
|
.getMongoObjectFactory(getMongoService());
|
||||||
|
protected DomainObjectFactoryImpl domainFactory = (DomainObjectFactoryImpl) MongoFactory.INSTANCE
|
||||||
|
.getDomainObjectFactory(getMongoService());
|
||||||
|
protected RaceLogEventFactory eventFactory = RaceLogEventFactory.INSTANCE;
|
||||||
|
|
||||||
|
public StoreAndLoadRaceLogsTest() throws UnknownHostException, MongoException {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreAndLoadSingleRaceLog() {
|
||||||
|
RaceLogIdentifier identifier = createIdentifier("A.A", "B.B", "C.C");
|
||||||
|
|
||||||
|
RaceLogFlagEvent event1 = createRaceLogFlagEvent(UUID.randomUUID());
|
||||||
|
RaceLogFlagEvent event2 = createRaceLogFlagEvent(UUID.randomUUID());
|
||||||
|
DBObject dbEvent1 = mongoFactory.storeRaceLogEntry(identifier, event1);
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent1);
|
||||||
|
DBObject dbEvent2 = mongoFactory.storeRaceLogEntry(identifier, event2);
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent2);
|
||||||
|
|
||||||
|
RaceLog raceLog = domainFactory.loadRaceLog(identifier);
|
||||||
|
try {
|
||||||
|
raceLog.lockForRead();
|
||||||
|
assertEquals(2, Util.size(raceLog.getRawFixes()));
|
||||||
|
} finally {
|
||||||
|
raceLog.unlockAfterRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreAndLoadCollidingRaceLogs() {
|
||||||
|
// RaceLog A.A B.B C.C
|
||||||
|
RaceLogIdentifier identifier = createIdentifier("A.A", "B.B", "C.C");
|
||||||
|
|
||||||
|
RaceLogFlagEvent event1 = createRaceLogFlagEvent(UUID.randomUUID());
|
||||||
|
RaceLogFlagEvent event2 = createRaceLogFlagEvent(UUID.randomUUID());
|
||||||
|
DBObject dbEvent1 = mongoFactory.storeRaceLogEntry(identifier, event1);
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent1);
|
||||||
|
DBObject dbEvent2 = mongoFactory.storeRaceLogEntry(identifier, event2);
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent2);
|
||||||
|
|
||||||
|
// RaceLog A.A.B B.C C
|
||||||
|
RaceLogIdentifier collidingIdentifier = createIdentifier("A.A.B", "B.C", "C");
|
||||||
|
|
||||||
|
RaceLogFlagEvent event3 = createRaceLogFlagEvent(UUID.randomUUID());
|
||||||
|
DBObject dbEvent3 = mongoFactory.storeRaceLogEntry(collidingIdentifier, event3);
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent3);
|
||||||
|
|
||||||
|
RaceLog raceLog = domainFactory.loadRaceLog(identifier);
|
||||||
|
try {
|
||||||
|
raceLog.lockForRead();
|
||||||
|
assertEquals(2, Util.size(raceLog.getRawFixes()));
|
||||||
|
} finally {
|
||||||
|
raceLog.unlockAfterRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testdLoadObsoleteIdentifier() {
|
||||||
|
// Identifier is A.A B.B C.C
|
||||||
|
|
||||||
|
DBObject dbEvent1 = (DBObject) com.mongodb.util.JSON.parse(createOldFormatRaceLogEventJson(UUID.randomUUID()));
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent1);
|
||||||
|
DBObject dbEvent2 = (DBObject) com.mongodb.util.JSON.parse(createOldFormatRaceLogEventJson(UUID.randomUUID()));
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent2);
|
||||||
|
|
||||||
|
RaceLog raceLog = domainFactory.loadRaceLog(createIdentifier("A.A", "B.B", "C.C"));
|
||||||
|
try {
|
||||||
|
raceLog.lockForRead();
|
||||||
|
assertEquals(2, Util.size(raceLog.getRawFixes()));
|
||||||
|
} finally {
|
||||||
|
raceLog.unlockAfterRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testdLoadObsoleteAndNewIdentifier() {
|
||||||
|
// event1 stored with obsolete identifier
|
||||||
|
DBObject dbEvent1 = (DBObject) com.mongodb.util.JSON.parse(createOldFormatRaceLogEventJson(UUID.randomUUID()));
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent1);
|
||||||
|
|
||||||
|
// event2 stored with new identifier
|
||||||
|
RaceLogIdentifier identifier = createIdentifier("A.A", "B.B", "C.C");
|
||||||
|
RaceLogFlagEvent event2 = createRaceLogFlagEvent(UUID.randomUUID());
|
||||||
|
DBObject dbEvent2 = mongoFactory.storeRaceLogEntry(identifier, event2);
|
||||||
|
mongoFactory.getRaceLogCollection().insert(dbEvent2);
|
||||||
|
|
||||||
|
RaceLog raceLog = domainFactory.loadRaceLog(identifier);
|
||||||
|
try {
|
||||||
|
raceLog.lockForRead();
|
||||||
|
assertEquals(2, Util.size(raceLog.getRawFixes()));
|
||||||
|
} finally {
|
||||||
|
raceLog.unlockAfterRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createOldFormatRaceLogEventJson(Serializable id) {
|
||||||
|
return "{ \"_id\" : { \"$oid\" : \""+ new ObjectId().toStringMongod() + "\"} , \"RACE_LOG_IDENTIFIER\" : \"A%2EA%2EB%2EB%2EC%2EC\" , \"RACE_LOG_EVENT\" : "
|
||||||
|
+ "{ \"TIME_AS_MILLIS\" : 42 , \"RACE_LOG_EVENT_CREATED_AT\" : 1376058090051 , \"RACE_LOG_EVENT_ID\" : { \"$uuid\" : \"" + id.toString() + "\"} , "
|
||||||
|
+ "\"RACE_LOG_EVENT_PASS_ID\" : 42 , \"RACE_LOG_EVENT_INVOLVED_BOATS\" : [ ] , \"RACE_LOG_EVENT_CLASS\" : \"RaceLogFlagEvent\" , \"RACE_LOG_EVENT_FLAG_UPPER\" : \"ALPHA\" , "
|
||||||
|
+ "\"RACE_LOG_EVENT_FLAG_LOWER\" : \"BRAVO\" , \"RACE_LOG_EVENT_FLAG_DISPLAYED\" : \"true\"}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private RaceLogIdentifier createIdentifier(String groupName, String raceColumnName, String fleetName) {
|
||||||
|
RaceLogIdentifierTemplate template = mock(RaceLogIdentifierTemplate.class);
|
||||||
|
when(template.getParentObjectName()).thenReturn(groupName);
|
||||||
|
when(template.getRaceColumnName()).thenReturn(raceColumnName);
|
||||||
|
Fleet fleet = mock(Fleet.class);
|
||||||
|
when(fleet.getName()).thenReturn(fleetName);
|
||||||
|
return new RaceLogIdentifierImpl(template, raceColumnName, fleet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RaceLogFlagEvent createRaceLogFlagEvent(Serializable id) {
|
||||||
|
return eventFactory.createFlagEvent(new MillisecondsTimePoint(42), id, Collections.<Competitor> emptyList(),
|
||||||
|
42, Flags.ALPHA, Flags.BRAVO, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-2
@@ -28,7 +28,7 @@ import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
|
|||||||
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
|
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
|
||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.ControlPointDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.ControlPointDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseDataDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseBaseDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.GateDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.GateDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.MarkDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.MarkDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDeserializer;
|
||||||
@@ -61,7 +61,7 @@ public class RaceLogCourseDesignChangedEventSerializerTest {
|
|||||||
new CourseBaseJsonSerializer(new WaypointJsonSerializer(new ControlPointJsonSerializer(
|
new CourseBaseJsonSerializer(new WaypointJsonSerializer(new ControlPointJsonSerializer(
|
||||||
new MarkJsonSerializer(), new GateJsonSerializer(new MarkJsonSerializer())))));
|
new MarkJsonSerializer(), new GateJsonSerializer(new MarkJsonSerializer())))));
|
||||||
deserializer = new RaceLogCourseDesignChangedEventDeserializer(new CompetitorDeserializer(factory),
|
deserializer = new RaceLogCourseDesignChangedEventDeserializer(new CompetitorDeserializer(factory),
|
||||||
new CourseDataDeserializer(new WaypointDeserializer(new ControlPointDeserializer(new MarkDeserializer(
|
new CourseBaseDeserializer(new WaypointDeserializer(new ControlPointDeserializer(new MarkDeserializer(
|
||||||
factory), new GateDeserializer(factory, new MarkDeserializer(factory))))));
|
factory), new GateDeserializer(factory, new MarkDeserializer(factory))))));
|
||||||
now = MillisecondsTimePoint.now();
|
now = MillisecondsTimePoint.now();
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -16,11 +16,11 @@ import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseBaseJs
|
|||||||
/**
|
/**
|
||||||
* Deserializer for CourseData.
|
* Deserializer for CourseData.
|
||||||
*/
|
*/
|
||||||
public class CourseDataDeserializer implements JsonDeserializer<CourseBase> {
|
public class CourseBaseDeserializer implements JsonDeserializer<CourseBase> {
|
||||||
|
|
||||||
private final WaypointDeserializer waypointDeserializer;
|
private final WaypointDeserializer waypointDeserializer;
|
||||||
|
|
||||||
public CourseDataDeserializer(WaypointDeserializer waypointDeserializer) {
|
public CourseBaseDeserializer(WaypointDeserializer waypointDeserializer) {
|
||||||
this.waypointDeserializer = waypointDeserializer;
|
this.waypointDeserializer = waypointDeserializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
+2
-2
@@ -17,8 +17,8 @@ public class Helpers {
|
|||||||
if (object instanceof JSONArray) {
|
if (object instanceof JSONArray) {
|
||||||
return (JSONArray) object;
|
return (JSONArray) object;
|
||||||
}
|
}
|
||||||
throw new JsonDeserializationException(String.format("Expected a JSONArray, got %s.", object.getClass()
|
throw new JsonDeserializationException(String.format("Expected a JSONArray, got %s.", object != null ? object.getClass()
|
||||||
.getName()));
|
.getName() : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSONObject toJSONObjectSafe(Object object) throws JsonDeserializationException {
|
public static JSONObject toJSONObjectSafe(Object object) throws JsonDeserializationException {
|
||||||
|
|||||||
+3
-3
@@ -11,14 +11,14 @@ import com.sap.sailing.domain.common.TimePoint;
|
|||||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseDataDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseBaseDeserializer;
|
||||||
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogCourseDesignChangedEventSerializer;
|
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogCourseDesignChangedEventSerializer;
|
||||||
|
|
||||||
public class RaceLogCourseDesignChangedEventDeserializer extends BaseRaceLogEventDeserializer {
|
public class RaceLogCourseDesignChangedEventDeserializer extends BaseRaceLogEventDeserializer {
|
||||||
|
|
||||||
private final CourseDataDeserializer courseDataDeserializer;
|
private final CourseBaseDeserializer courseDataDeserializer;
|
||||||
|
|
||||||
public RaceLogCourseDesignChangedEventDeserializer(JsonDeserializer<Competitor> competitorDeserializer, CourseDataDeserializer courseDataDeserializer) {
|
public RaceLogCourseDesignChangedEventDeserializer(JsonDeserializer<Competitor> competitorDeserializer, CourseBaseDeserializer courseDataDeserializer) {
|
||||||
super(competitorDeserializer);
|
super(competitorDeserializer);
|
||||||
this.courseDataDeserializer = courseDataDeserializer;
|
this.courseDataDeserializer = courseDataDeserializer;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,7 +8,7 @@ import com.sap.sailing.domain.racelog.RaceLogEvent;
|
|||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.ControlPointDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.ControlPointDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseDataDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseBaseDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.GateDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.GateDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.MarkDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.MarkDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDeserializer;
|
||||||
@@ -40,7 +40,7 @@ public class RaceLogEventDeserializer implements JsonDeserializer<RaceLogEvent>
|
|||||||
new RaceLogRaceStatusEventDeserializer(competitorDeserializer),
|
new RaceLogRaceStatusEventDeserializer(competitorDeserializer),
|
||||||
new RaceLogCourseAreaChangedEventDeserializer(competitorDeserializer),
|
new RaceLogCourseAreaChangedEventDeserializer(competitorDeserializer),
|
||||||
new RaceLogCourseDesignChangedEventDeserializer(competitorDeserializer,
|
new RaceLogCourseDesignChangedEventDeserializer(competitorDeserializer,
|
||||||
new CourseDataDeserializer(
|
new CourseBaseDeserializer(
|
||||||
new WaypointDeserializer(
|
new WaypointDeserializer(
|
||||||
new ControlPointDeserializer(
|
new ControlPointDeserializer(
|
||||||
new MarkDeserializer(domainFactory), new GateDeserializer(domainFactory, new MarkDeserializer(domainFactory)))))),
|
new MarkDeserializer(domainFactory), new GateDeserializer(domainFactory, new MarkDeserializer(domainFactory)))))),
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ public class RaceLogSerializer implements JsonSerializer<RaceLog> {
|
|||||||
events.add(itemSerializer.serialize(event));
|
events.add(itemSerializer.serialize(event));
|
||||||
}
|
}
|
||||||
result.put(FIELD_EVENTS, events);
|
result.put(FIELD_EVENTS, events);
|
||||||
result.put(FIELD_RACELOG_IDENTIFIER, object.getId());
|
result.put(FIELD_RACELOG_IDENTIFIER, object.getId().toString());
|
||||||
} finally {
|
} finally {
|
||||||
object.unlockAfterRead();
|
object.unlockAfterRead();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import com.sap.sailing.server.RacingEventService;
|
|||||||
|
|
||||||
public abstract class AbstractSeriesOperation<ResultType> extends AbstractRacingEventServiceOperation<ResultType> {
|
public abstract class AbstractSeriesOperation<ResultType> extends AbstractRacingEventServiceOperation<ResultType> {
|
||||||
private static final long serialVersionUID = -7786133902346491275L;
|
private static final long serialVersionUID = -7786133902346491275L;
|
||||||
private Logger logger = Logger.getLogger(AbstractSeriesOperation.class.getName());
|
private static final Logger logger = Logger.getLogger(AbstractSeriesOperation.class.getName());
|
||||||
private final RegattaIdentifier regattaIdentifier;
|
private final RegattaIdentifier regattaIdentifier;
|
||||||
private final String seriesName;
|
private final String seriesName;
|
||||||
|
|
||||||
|
|||||||
+6
@@ -500,4 +500,10 @@ public class DummyTrackedRace implements TrackedRace {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimePoint getStartTimeReceived() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,25 +19,12 @@
|
|||||||
<div id='mainContent'>
|
<div id='mainContent'>
|
||||||
<h1 id='pageHeadline'>Extreme Sailing Series 2013</h1>
|
<h1 id='pageHeadline'>Extreme Sailing Series 2013</h1>
|
||||||
<h2>Next Event</h2>
|
<h2>Next Event</h2>
|
||||||
<p>
|
|
||||||
Act 5 - Porto, Portugal
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
July 25th - 28th
|
|
||||||
</p>
|
|
||||||
<!--<p>
|
|
||||||
Act 6 - Cardiff, England
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
August 22th - 25th
|
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
Act 7 - Nice, France
|
Act 7 - Nice, France
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
October 3th - 6th
|
September 2th - 6th
|
||||||
</p>
|
</p>
|
||||||
-->
|
|
||||||
</div>
|
</div>
|
||||||
<div id='navigation'>
|
<div id='navigation'>
|
||||||
<a class='navButton overall' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=Extreme%20Sailing%20Series%202013%20Overall&showRaceDetails=false&refreshIntervalMillis=10000&displayName=Overall%20Standings&leaderboardGroupName=Extreme%20Sailing%20Series%202013&root=leaderboardGroupPanel'>
|
<a class='navButton overall' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=Extreme%20Sailing%20Series%202013%20Overall&showRaceDetails=false&refreshIntervalMillis=10000&displayName=Overall%20Standings&leaderboardGroupName=Extreme%20Sailing%20Series%202013&root=leaderboardGroupPanel'>
|
||||||
@@ -48,10 +35,10 @@
|
|||||||
</a>
|
</a>
|
||||||
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=ESS%202013%20Nice%20%28Extreme40%29&displayName=Nice&delayToLiveMillis=3000&refreshIntervalMillis=10000&legDetail=AVERAGE_SPEED_OVER_GROUND_IN_KNOTS&legDetail=DISTANCE_TRAVELED&legDetail=RANK_GAIN&raceDetail=DISPLAY_LEGS&maneuverDetail=TACK&maneuverDetail=JIBE&maneuverDetail=PENALTY_CIRCLE&lastN=3'>
|
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=ESS%202013%20Nice%20%28Extreme40%29&displayName=Nice&delayToLiveMillis=3000&refreshIntervalMillis=10000&legDetail=AVERAGE_SPEED_OVER_GROUND_IN_KNOTS&legDetail=DISTANCE_TRAVELED&legDetail=RANK_GAIN&raceDetail=DISPLAY_LEGS&maneuverDetail=TACK&maneuverDetail=JIBE&maneuverDetail=PENALTY_CIRCLE&lastN=3'>
|
||||||
Nice
|
Nice
|
||||||
</a>
|
</a>-->
|
||||||
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=ESS%202013%20Cardiff%20%28Extreme40%29&displayName=Cardiff&delayToLiveMillis=3000&refreshIntervalMillis=10000&legDetail=AVERAGE_SPEED_OVER_GROUND_IN_KNOTS&legDetail=DISTANCE_TRAVELED&legDetail=RANK_GAIN&raceDetail=DISPLAY_LEGS&maneuverDetail=TACK&maneuverDetail=JIBE&maneuverDetail=PENALTY_CIRCLE&lastN=3'>
|
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=ESS%202013%20Cardiff%20%28Extreme40%29&displayName=Cardiff&delayToLiveMillis=3000&refreshIntervalMillis=10000&legDetail=AVERAGE_SPEED_OVER_GROUND_IN_KNOTS&legDetail=DISTANCE_TRAVELED&legDetail=RANK_GAIN&raceDetail=DISPLAY_LEGS&maneuverDetail=TACK&maneuverDetail=JIBE&maneuverDetail=PENALTY_CIRCLE&lastN=3'>
|
||||||
Cardiff
|
Cardiff
|
||||||
</a>-->
|
</a>
|
||||||
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=ESS%202013%20Porto%20%28Extreme40%29&displayName=Porto&delayToLiveMillis=3000&refreshIntervalMillis=10000&legDetail=AVERAGE_SPEED_OVER_GROUND_IN_KNOTS&legDetail=DISTANCE_TRAVELED&legDetail=RANK_GAIN&raceDetail=DISPLAY_LEGS&maneuverDetail=TACK&maneuverDetail=JIBE&maneuverDetail=PENALTY_CIRCLE&lastN=3'>
|
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=ESS%202013%20Porto%20%28Extreme40%29&displayName=Porto&delayToLiveMillis=3000&refreshIntervalMillis=10000&legDetail=AVERAGE_SPEED_OVER_GROUND_IN_KNOTS&legDetail=DISTANCE_TRAVELED&legDetail=RANK_GAIN&raceDetail=DISPLAY_LEGS&maneuverDetail=TACK&maneuverDetail=JIBE&maneuverDetail=PENALTY_CIRCLE&lastN=3'>
|
||||||
Porto
|
Porto
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -33,22 +33,64 @@
|
|||||||
|
|
||||||
<div class='innerContent'>
|
<div class='innerContent'>
|
||||||
<!-- Uncomment the following in case there are events in live state and add the timeBar plus raceSection -->
|
<!-- Uncomment the following in case there are events in live state and add the timeBar plus raceSection -->
|
||||||
<!--
|
|
||||||
<h2 class='articleSubheadline'>Live</h2>
|
<!--<h2 class='articleSubheadline'>Live</h2>
|
||||||
<br/>
|
<br/>
|
||||||
-->
|
<div class="timeBar">
|
||||||
|
</div>-->
|
||||||
|
|
||||||
|
|
||||||
<!-- Uncomment the following in case there are upcoming and add the timeBar plus raceSection -->
|
<!-- Uncomment the following in case there are upcoming and add the timeBar plus raceSection -->
|
||||||
<!--
|
|
||||||
<h2 class='articleSubheadline'>Upcoming</h2>
|
<h2 class='articleSubheadline'>Upcoming</h2>
|
||||||
<div class="timeBar">
|
<div class="timeBar">
|
||||||
|
<div class='raceSection'>
|
||||||
|
<h5 class='date'>
|
||||||
|
Sep 2 - 7
|
||||||
|
</h5>
|
||||||
|
<div class='raceTimepoint'></div>
|
||||||
|
<a href='http://ess40-2013.sapsailing.com' target='_blank'>
|
||||||
|
<ul class='racePanel'>
|
||||||
|
<li class='raceName'>
|
||||||
|
Extreme Sailing Series 2013
|
||||||
|
</li>
|
||||||
|
<li class='raceLocation'>
|
||||||
|
Nice, France
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</a>
|
||||||
|
<div class='raceDescription'>
|
||||||
|
<p>Extreme Sailing Series 2013</p>
|
||||||
|
<a href='http://ess40-2013.sapsailing.com' target='_blank'>SAP Sailing Analytics</a><br/>
|
||||||
|
<a href='http://www.extremesailingseries.com' target='_blank'>Official website</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
-->
|
|
||||||
|
|
||||||
<h2 class='articleSubheadline'>2013</h2>
|
<h2 class='articleSubheadline'>2013</h2>
|
||||||
<div class="timeBar">
|
<div class="timeBar">
|
||||||
|
<div class='raceSection'>
|
||||||
|
<h5 class='date'>
|
||||||
|
Aug 23 - 26
|
||||||
|
</h5>
|
||||||
|
<div class='raceTimepoint'></div>
|
||||||
|
<a href='http://ess40-2013.sapsailing.com' target='_blank'>
|
||||||
|
<ul class='racePanel'>
|
||||||
|
<li class='raceName'>
|
||||||
|
Extreme Sailing Series 2013
|
||||||
|
</li>
|
||||||
|
<li class='raceLocation'>
|
||||||
|
Cardiff, Wales
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</a>
|
||||||
|
<div class='raceDescription'>
|
||||||
|
<p>Extreme Sailing Series 2013</p>
|
||||||
|
<a href='http://ess40-2013.sapsailing.com' target='_blank'>SAP Sailing Analytics</a><br/>
|
||||||
|
<a href='http://www.extremesailingseries.com' target='_blank'>Official website</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class='raceSection'>
|
<div class='raceSection'>
|
||||||
<h5 class='date'>
|
<h5 class='date'>
|
||||||
July 19 - 28
|
July 19 - 28
|
||||||
@@ -111,28 +153,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='raceSection'>
|
|
||||||
<h5 class='date'>
|
|
||||||
July 25 - 28
|
|
||||||
</h5>
|
|
||||||
<div class='raceTimepoint'></div>
|
|
||||||
<a href='http://ess40-2013.sapsailing.com' target='_blank'>
|
|
||||||
<ul class='racePanel'>
|
|
||||||
<li class='raceName'>
|
|
||||||
Extreme Sailing Series 2013
|
|
||||||
</li>
|
|
||||||
<li class='raceLocation'>
|
|
||||||
Porto, Portugal
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</a>
|
|
||||||
<div class='raceDescription'>
|
|
||||||
<p>Extreme Sailing Series 2013</p>
|
|
||||||
<a href='http://ess40-2013.sapsailing.com' target='_blank'>SAP Sailing Analytics</a><br/>
|
|
||||||
<a href='http://www.extremesailingseries.com' target='_blank'>Official website</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class='raceSection'>
|
<div class='raceSection'>
|
||||||
<h5 class='date'>
|
<h5 class='date'>
|
||||||
May 1 - 5
|
May 1 - 5
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
monitor.interval = 30000
|
monitor.interval = 30000
|
||||||
|
|
||||||
# time the monitoring server waits before polling, in milliseconds
|
# time the monitoring server waits before polling, in milliseconds
|
||||||
monitor.gracetime = 10000
|
monitor.gracetime = 60000
|
||||||
|
|
||||||
# time between interval checks, in milliseconds
|
# time between interval checks, in milliseconds
|
||||||
monitor.pause = 1000
|
monitor.pause = 1000
|
||||||
|
|||||||
@@ -45,7 +45,8 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ui.activities.LoginActivity"
|
android:name=".ui.activities.LoginActivity"
|
||||||
android:screenOrientation="landscape"
|
android:screenOrientation="landscape"
|
||||||
android:launchMode="singleTop" >
|
android:launchMode="standard"
|
||||||
|
android:finishOnTaskLaunch="true" >
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|||||||
Regular → Executable
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
Regular → Executable
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.4 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
@@ -2,10 +2,15 @@
|
|||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/settings_category_general" >
|
<PreferenceCategory android:title="@string/settings_category_general" >
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="languagePref"
|
||||||
|
android:title="@string/settings_general_language_header"
|
||||||
|
android:summary="@string/settings_general_language_description"/>
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
|
android:key="courseAreasPref"
|
||||||
android:name="@string/settings_general_manageareas_header"
|
android:name="@string/settings_general_manageareas_header"
|
||||||
android:defaultValue="@string/settings_general_manageareas_default"
|
android:defaultValue="@string/settings_general_manageareas_default"
|
||||||
android:key="courseAreasPref"
|
|
||||||
android:summary="@string/settings_general_manageareas_description"
|
android:summary="@string/settings_general_manageareas_description"
|
||||||
android:title="@string/settings_general_manageareas_header" />
|
android:title="@string/settings_general_manageareas_header" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<TextView android:id="@+id/Welter.Cell.OneRowNoImage.txtTitle"
|
<TextView android:id="@+id/Welter.Cell.OneRowNoImage.txtTitle"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:textColor="@drawable/text_selector"
|
android:textColor="@drawable/text_selector"
|
||||||
android:textSize="10pt"
|
android:textSize="@dimen/Welter.BigTitleTextSize"
|
||||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true">
|
android:layout_centerVertical="true">
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|||||||
+2
-2
@@ -15,14 +15,14 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:textSize="10pt" android:alpha="1" >
|
android:textSize="@dimen/Welter.RegularTextSize" android:alpha="1" >
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/Welter.Cell.OneRowNoImageLabel.btnJury"
|
<ImageButton android:id="@+id/Welter.Cell.OneRowNoImageLabel.btnJury"
|
||||||
android:src="@drawable/bravo_mini"
|
android:src="@drawable/bravo_mini"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:textColor="@color/welter_red"
|
android:textColor="@color/welter_red"
|
||||||
android:textSize="10pt"
|
android:textSize="@dimen/Welter.RegularTextSize"
|
||||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
android:contentDescription="@string/flag_jury"
|
android:contentDescription="@string/flag_jury"
|
||||||
android:layout_centerVertical="true" android:layout_alignParentRight="true" />
|
android:layout_centerVertical="true" android:layout_alignParentRight="true" />
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:text="Title of the first line"
|
android:text="@string/empty"
|
||||||
android:textColor="@drawable/text_selector"
|
android:textColor="@drawable/text_selector"
|
||||||
android:textSize="9pt" >
|
android:textSize="@dimen/Welter.RegularTextSize" >
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -30,8 +30,8 @@
|
|||||||
android:paddingLeft="6pt"
|
android:paddingLeft="6pt"
|
||||||
android:layout_below="@+id/Welter.Cell.TwoRowNoImage.lineOne"
|
android:layout_below="@+id/Welter.Cell.TwoRowNoImage.lineOne"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:text="Title of the second line"
|
android:text="@string/empty"
|
||||||
android:textSize="8pt" >
|
android:textSize="@dimen/Welter.ProgressTextSize" >
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|||||||
@@ -2,23 +2,23 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="horizontal"
|
android:background="@drawable/background"
|
||||||
android:descendantFocusability="beforeDescendants"
|
android:descendantFocusability="beforeDescendants"
|
||||||
android:focusableInTouchMode="true"
|
android:focusableInTouchMode="true"
|
||||||
android:background="@drawable/background" >
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_margin="18dp"
|
android:layout_margin="18dp"
|
||||||
android:background="@color/welter_extralight_gray_transparent">
|
android:background="@color/welter_extralight_gray_transparent"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="18dp">
|
android:layout_margin="18dp"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -26,50 +26,6 @@
|
|||||||
android:text="@string/enter_wind_direction"
|
android:text="@string/enter_wind_direction"
|
||||||
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabel" />
|
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabel" />
|
||||||
|
|
||||||
<com.sap.sailing.racecommittee.app.ui.views.CompassView
|
|
||||||
android:id="@+id/compassView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" >
|
|
||||||
</com.sap.sailing.racecommittee.app.ui.views.CompassView>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/enter_wind_speed"
|
|
||||||
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabel" />
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:id="@+id/seekbar_wind_speed"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:progress="100"
|
|
||||||
android:max="250"
|
|
||||||
android:padding="18dp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="2dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_margin="18dp"
|
|
||||||
android:background="@color/welter_deep_gray">
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="18dp"
|
|
||||||
android:layout_marginRight="26dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="9dp"
|
|
||||||
android:text="@string/check_all_data"
|
|
||||||
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabel" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -79,9 +35,38 @@
|
|||||||
android:id="@+id/editTextWindDirection"
|
android:id="@+id/editTextWindDirection"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="numberDecimal"
|
|
||||||
android:hint="@string/in_degrees"
|
android:hint="@string/in_degrees"
|
||||||
android:minWidth="200dp" />
|
android:inputType="numberDecimal"
|
||||||
|
android:minWidth="200dp"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<com.sap.sailing.racecommittee.app.ui.views.CompassView
|
||||||
|
android:id="@+id/compassView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
</com.sap.sailing.racecommittee.app.ui.views.CompassView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="2dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="18dp"
|
||||||
|
android:background="@color/welter_deep_gray"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="18dp"
|
||||||
|
android:layout_marginRight="26dp"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/enter_wind_speed"
|
||||||
|
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabel" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -92,49 +77,42 @@
|
|||||||
android:id="@+id/editTextWindSpeed"
|
android:id="@+id/editTextWindSpeed"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="numberDecimal"
|
|
||||||
android:hint="@string/in_knots"
|
android:hint="@string/in_knots"
|
||||||
android:minWidth="200dp">
|
android:inputType="numberDecimal"
|
||||||
</EditText>
|
android:minWidth="200dp"
|
||||||
|
android:textSize="24sp" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekbar_wind_speed"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:max="500"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:progress="100" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/your_position" />
|
android:layout_marginBottom="9dp"
|
||||||
|
android:text="@string/check_all_data"
|
||||||
|
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabel" />
|
||||||
|
|
||||||
<EditText
|
<TextView
|
||||||
android:id="@+id/et_position_lat"
|
android:id="@+id/textWaitingForGPS"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/latitude"
|
android:text="@string/waiting_for_gps"
|
||||||
android:minWidth="200dp"
|
android:textAppearance="@style/TextAppearance.Welter.TitleLabel"
|
||||||
android:clickable="false"
|
android:textColor="@color/welter_red"
|
||||||
android:cursorVisible="false"
|
android:textSize="24sp" />
|
||||||
android:focusable="false"
|
|
||||||
android:focusableInTouchMode="false">
|
|
||||||
</EditText>
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/et_position_lon"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="@string/longitude"
|
|
||||||
android:minWidth="200dp"
|
|
||||||
android:clickable="false"
|
|
||||||
android:cursorVisible="false"
|
|
||||||
android:focusable="false"
|
|
||||||
android:focusableInTouchMode="false">
|
|
||||||
</EditText>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btn_wind_send"
|
android:id="@+id/btn_wind_send"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/store_wind"
|
android:layout_gravity="center"
|
||||||
android:layout_gravity="center"/>
|
android:text="@string/store_wind" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
<string name="course_design_number_waypoints">Kurs hat %s Wegpunkte</string>
|
<string name="course_design_number_waypoints">Kurs hat %s Wegpunkte</string>
|
||||||
<string name="choose_running_course">Wähle Kurs aus</string>
|
<string name="choose_running_course">Wähle Kurs aus</string>
|
||||||
<string name="service_info">SAP Race Committee Service</string>
|
<string name="service_info">SAP Race Committee Service</string>
|
||||||
<string name="service_title">Verwaltet alle Rennen auf gewählter Rennbahn.</string>
|
<string name="service_text_no_races">Warte auf Rennen…</string>
|
||||||
|
<string name="service_text_num_races">Aktuell %d Rennen verwaltet.</string>
|
||||||
|
|
||||||
<string name="app_name">SAP Race Committee Cockpit</string>
|
<string name="app_name">SAP Race Committee Cockpit</string>
|
||||||
<string name="set_time">Start</string>
|
<string name="set_time">Start</string>
|
||||||
<string name="reset_time">Startzeit ändern</string>
|
<string name="reset_time">Startzeit ändern</string>
|
||||||
@@ -179,6 +181,7 @@
|
|||||||
<string name="wind_speed_direction_not_a_valid_number">Die Windgeschwindigkeit oder -richtung ist keine valide Zahl. Bitte korrigieren Sie den Wert.</string>
|
<string name="wind_speed_direction_not_a_valid_number">Die Windgeschwindigkeit oder -richtung ist keine valide Zahl. Bitte korrigieren Sie den Wert.</string>
|
||||||
<string name="wind_location_or_fields_not_valid">Die eingegebene Position, Windgeschwindigkeit oder -richtung ist leer. Bitte korrigieren Sie die Werte.</string>
|
<string name="wind_location_or_fields_not_valid">Die eingegebene Position, Windgeschwindigkeit oder -richtung ist leer. Bitte korrigieren Sie die Werte.</string>
|
||||||
<string name="your_position">Aktuelle Position</string>
|
<string name="your_position">Aktuelle Position</string>
|
||||||
|
<string name="waiting_for_gps">Warte auf GPS Signal…</string>
|
||||||
<string name="store_wind_entry">4. Windeingaben speichern</string>
|
<string name="store_wind_entry">4. Windeingaben speichern</string>
|
||||||
<string name="store_wind">Windeingaben speichern</string>
|
<string name="store_wind">Windeingaben speichern</string>
|
||||||
|
|
||||||
@@ -186,6 +189,8 @@
|
|||||||
<string name="settings_category_general">Allgemeine Einstellungen</string>
|
<string name="settings_category_general">Allgemeine Einstellungen</string>
|
||||||
<string name="settings_general_manageareas_header">Verwaltete Rennbahnen</string>
|
<string name="settings_general_manageareas_header">Verwaltete Rennbahnen</string>
|
||||||
<string name="settings_general_manageareas_description">Verwaltete Rennbahnen einstellen (Komma-getrennt)</string>
|
<string name="settings_general_manageareas_description">Verwaltete Rennbahnen einstellen (Komma-getrennt)</string>
|
||||||
|
<string name="settings_general_language_header">Sprache auswählen</string>
|
||||||
|
<string name="settings_general_language_description">Sprache auswählen. Eventuell muss die App neugestartet werden.</string>
|
||||||
|
|
||||||
<string name="settings_category_race">Renneinstellungen</string>
|
<string name="settings_category_race">Renneinstellungen</string>
|
||||||
<string name="override_default_start_procedure_type_header">Standard Startprozedur überschreiben</string>
|
<string name="override_default_start_procedure_type_header">Standard Startprozedur überschreiben</string>
|
||||||
@@ -196,7 +201,7 @@
|
|||||||
<string name="settings_time_frame_description">Zeit in Minuten einstellen, welches Zeitlimit angibt</string>
|
<string name="settings_time_frame_description">Zeit in Minuten einstellen, welches Zeitlimit angibt</string>
|
||||||
|
|
||||||
<string name="settings_category_advanced">Erweiterte Einstellungen</string>
|
<string name="settings_category_advanced">Erweiterte Einstellungen</string>
|
||||||
<string name="settings_advanced_service_header">Wählen sie die Server URL aus.</string>
|
<string name="settings_advanced_service_header">Wählen sie die Server URL aus. Nach Änderung muss die Option \'Neuladen\' gewählt werden.</string>
|
||||||
<string name="settings_advanced_service_description">Webservice URL einstellen.</string>
|
<string name="settings_advanced_service_description">Webservice URL einstellen.</string>
|
||||||
<string name="settings_advanced_mail_description">Empfänger für Bilder der Ergebnislisten.</string>
|
<string name="settings_advanced_mail_description">Empfänger für Bilder der Ergebnislisten.</string>
|
||||||
<string name="settings_advanced_mail_header">Empfänger Ergebnislisten</string>
|
<string name="settings_advanced_mail_header">Empfänger Ergebnislisten</string>
|
||||||
@@ -233,4 +238,8 @@
|
|||||||
<string name="number">Nummer</string>
|
<string name="number">Nummer</string>
|
||||||
<string name="snap">Fotos schießen</string>
|
<string name="snap">Fotos schießen</string>
|
||||||
|
|
||||||
|
<string name="logout_dialog_title">Möchten Sie sich abmelden?</string>
|
||||||
|
<string name="logout_dialog_message">Wenn Sie sich abmelden wird kein Rennen mehr verwaltet.</string>
|
||||||
|
<string name="logout">Abmelden</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
<string name="course_design_number_waypoints">Course has %s waypoints</string>
|
<string name="course_design_number_waypoints">Course has %s waypoints</string>
|
||||||
<string name="choose_running_course">Choose running course</string>
|
<string name="choose_running_course">Choose running course</string>
|
||||||
<string name="service_info">SAP Race Committee Service</string>
|
<string name="service_info">SAP Race Committee Service</string>
|
||||||
<string name="service_title">Monitoring all races on selected event course.</string>
|
<string name="service_text_no_races">Waiting for races to monitor…</string>
|
||||||
|
<string name="service_text_num_races">Currently monitoring %d races.</string>
|
||||||
|
|
||||||
<string name="app_name">SAP Race Committee Cockpit</string>
|
<string name="app_name">SAP Race Committee Cockpit</string>
|
||||||
<string name="set_time">Start</string>
|
<string name="set_time">Start</string>
|
||||||
<string name="reset_time">Restart</string>
|
<string name="reset_time">Restart</string>
|
||||||
@@ -167,7 +169,7 @@
|
|||||||
|
|
||||||
<string name="results_mail_subject">[Race Committee] %s</string>
|
<string name="results_mail_subject">[Race Committee] %s</string>
|
||||||
<string name="results_mail_body">Results for race %s are attached.</string>
|
<string name="results_mail_body">Results for race %s are attached.</string>
|
||||||
<string name="wind_direction_degrees">Wind direction (degrees)</string>
|
<string name="wind_direction_degrees">Wind direction from (degrees)</string>
|
||||||
<string name="wind_speed_knots">Wind speed (knots)</string>
|
<string name="wind_speed_knots">Wind speed (knots)</string>
|
||||||
<string name="enter_wind_direction">1. Enter the wind direction</string>
|
<string name="enter_wind_direction">1. Enter the wind direction</string>
|
||||||
<string name="enter_wind_speed">2. Enter the wind speed</string>
|
<string name="enter_wind_speed">2. Enter the wind speed</string>
|
||||||
@@ -178,7 +180,7 @@
|
|||||||
<string name="longitude">Longitude</string>
|
<string name="longitude">Longitude</string>
|
||||||
<string name="wind_speed_direction_not_a_valid_number">The wind speed or direction is not a valid number. Please correct the value.</string>
|
<string name="wind_speed_direction_not_a_valid_number">The wind speed or direction is not a valid number. Please correct the value.</string>
|
||||||
<string name="wind_location_or_fields_not_valid">The entered location, wind speed or direction is empty. Please correct the values.</string>
|
<string name="wind_location_or_fields_not_valid">The entered location, wind speed or direction is empty. Please correct the values.</string>
|
||||||
<string name="your_position">Your position</string>
|
<string name="waiting_for_gps">Waiting for GPS Signal…</string>
|
||||||
<string name="store_wind_entry">4. Store wind entry</string>
|
<string name="store_wind_entry">4. Store wind entry</string>
|
||||||
<string name="store_wind">Store wind</string>
|
<string name="store_wind">Store wind</string>
|
||||||
|
|
||||||
@@ -186,6 +188,8 @@
|
|||||||
<string name="settings_category_general">General Settings</string>
|
<string name="settings_category_general">General Settings</string>
|
||||||
<string name="settings_general_manageareas_header">Managed Course Areas</string>
|
<string name="settings_general_manageareas_header">Managed Course Areas</string>
|
||||||
<string name="settings_general_manageareas_description">Enter course area names managed by you (comma-separated)</string>
|
<string name="settings_general_manageareas_description">Enter course area names managed by you (comma-separated)</string>
|
||||||
|
<string name="settings_general_language_header">Select Language</string>
|
||||||
|
<string name="settings_general_language_description">Select the language. You might need to restart the app to have changes applied.</string>
|
||||||
|
|
||||||
<string name="settings_category_race">Race Settings</string>
|
<string name="settings_category_race">Race Settings</string>
|
||||||
<string name="override_default_start_procedure_type_header">Override default start procedure type</string>
|
<string name="override_default_start_procedure_type_header">Override default start procedure type</string>
|
||||||
@@ -262,4 +266,8 @@
|
|||||||
<string name="confirm_positionings">Confirm positionings</string>
|
<string name="confirm_positionings">Confirm positionings</string>
|
||||||
<string name="snap">Snap</string>
|
<string name="snap">Snap</string>
|
||||||
|
|
||||||
|
<string name="logout_dialog_title">Are you sure want to logout?</string>
|
||||||
|
<string name="logout_dialog_message">Logging out stops automatic monitoring for all races.</string>
|
||||||
|
<string name="logout">Logout</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
+1
@@ -6,6 +6,7 @@ import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.SetStartTimeRaceF
|
|||||||
public class AppConstants {
|
public class AppConstants {
|
||||||
|
|
||||||
public static final boolean IS_DATA_OFFLINE = false;
|
public static final boolean IS_DATA_OFFLINE = false;
|
||||||
|
public static final boolean ENABLE_LIFECYCLE_LOGGING = false;
|
||||||
|
|
||||||
// Intent extra fields
|
// Intent extra fields
|
||||||
public final static String COURSE_AREA_UUID_KEY = "courseUuid";
|
public final static String COURSE_AREA_UUID_KEY = "courseUuid";
|
||||||
|
|||||||
+2
-2
@@ -109,13 +109,13 @@ public class AppPreferences {
|
|||||||
return Arrays.asList(managedCourseAreas);
|
return Arrays.asList(managedCourseAreas);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getWindBearing(Context context) {
|
public static double getWindBearingFromDirection(Context context) {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
long windBearingAsLong = sp.getLong(PREFERENCE_WIND_BEARING, 0);
|
long windBearingAsLong = sp.getLong(PREFERENCE_WIND_BEARING, 0);
|
||||||
return Double.longBitsToDouble(windBearingAsLong);
|
return Double.longBitsToDouble(windBearingAsLong);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setWindBearing(Context context, double enteredWindBearing) {
|
public static void setWindBearingFromDirection(Context context, double enteredWindBearing) {
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
long windBearingAsLong = Double.doubleToLongBits(enteredWindBearing);
|
long windBearingAsLong = Double.doubleToLongBits(enteredWindBearing);
|
||||||
sp.edit().putLong(PREFERENCE_WIND_BEARING, windBearingAsLong).apply();
|
sp.edit().putLong(PREFERENCE_WIND_BEARING, windBearingAsLong).apply();
|
||||||
|
|||||||
+5
-4
@@ -4,13 +4,14 @@ import java.lang.Thread.UncaughtExceptionHandler;
|
|||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
|
||||||
import com.sap.sailing.racecommittee.app.logging.FileLoggingTask;
|
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.FileLoggingTask;
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.LifecycleLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a additional exception handler for uncaught exception to have some crash logging.
|
* Register a additional exception handler for uncaught exception to have some crash logging.
|
||||||
*/
|
*/
|
||||||
@@ -27,12 +28,12 @@ public class RaceApplication extends Application {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
ExLog.i(TAG, "Application is starting");
|
ExLog.i(TAG, "Application is starting");
|
||||||
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new LoggingExceptionHandler(Thread
|
Thread.setDefaultUncaughtExceptionHandler(new LoggingExceptionHandler(Thread
|
||||||
.getDefaultUncaughtExceptionHandler()));
|
.getDefaultUncaughtExceptionHandler()));
|
||||||
|
|
||||||
|
LifecycleLogger.enableLifecycleLogging(AppConstants.ENABLE_LIFECYCLE_LOGGING);
|
||||||
stringContext = new StringContext(new WeakReference<Context>(getApplicationContext()));
|
stringContext = new StringContext(new WeakReference<Context>(getApplicationContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-2
@@ -4,18 +4,23 @@ import com.sap.sailing.racecommittee.app.AppConstants;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all data managers. Use {@link DataManager#create(Context)} for creating your {@link DataManager}.
|
||||||
|
*/
|
||||||
public abstract class DataManager implements ReadonlyDataManager {
|
public abstract class DataManager implements ReadonlyDataManager {
|
||||||
|
|
||||||
public static ReadonlyDataManager create(Context context) {
|
public static ReadonlyDataManager create(Context context) {
|
||||||
if (AppConstants.IS_DATA_OFFLINE) {
|
if (AppConstants.IS_DATA_OFFLINE) {
|
||||||
return new OfflineDataManager(InMemoryDataStore.INSTANCE);
|
return new OfflineDataManager(context, InMemoryDataStore.INSTANCE);
|
||||||
}
|
}
|
||||||
return new OnlineDataManager(context, InMemoryDataStore.INSTANCE);
|
return new OnlineDataManager(context, InMemoryDataStore.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Context context;
|
||||||
protected DataStore dataStore;
|
protected DataStore dataStore;
|
||||||
|
|
||||||
public DataManager(DataStore dataStore) {
|
public DataManager(Context context, DataStore dataStore) {
|
||||||
|
this.context = context;
|
||||||
this.dataStore = dataStore;
|
this.dataStore = dataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,4 +28,8 @@ public abstract class DataManager implements ReadonlyDataManager {
|
|||||||
return dataStore;
|
return dataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+90
-72
@@ -7,6 +7,10 @@ import java.util.Collection;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import android.app.LoaderManager.LoaderCallbacks;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.CourseArea;
|
import com.sap.sailing.domain.base.CourseArea;
|
||||||
@@ -31,6 +35,8 @@ import com.sap.sailing.domain.racelog.RaceLogEventFactory;
|
|||||||
import com.sap.sailing.domain.racelog.impl.RaceLogEventFactoryImpl;
|
import com.sap.sailing.domain.racelog.impl.RaceLogEventFactoryImpl;
|
||||||
import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
|
import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
|
||||||
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderResult;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.ImmediateDataLoaderCallbacks;
|
||||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceIdentifierImpl;
|
import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceIdentifierImpl;
|
||||||
import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceImpl;
|
import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceImpl;
|
||||||
@@ -39,8 +45,8 @@ public class OfflineDataManager extends DataManager {
|
|||||||
|
|
||||||
private static boolean isInitialized = false;
|
private static boolean isInitialized = false;
|
||||||
|
|
||||||
public OfflineDataManager(DataStore dataStore) {
|
public OfflineDataManager(Context context, DataStore dataStore) {
|
||||||
super(dataStore);
|
super(context, dataStore);
|
||||||
|
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
@@ -49,7 +55,8 @@ public class OfflineDataManager extends DataManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fillDataStore(DataStore dataStore) {
|
private void fillDataStore(DataStore dataStore) {
|
||||||
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Cardiff)", "Cardiff", "", true, "DUMBUUIDA"));
|
dataStore
|
||||||
|
.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Cardiff)", "Cardiff", "", true, "DUMBUUIDA"));
|
||||||
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Nice)", "Nice", "", true, "DUMBUUIDB"));
|
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Nice)", "Nice", "", true, "DUMBUUIDB"));
|
||||||
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Rio)", "Rio", "", true, "DUMBUUIDC"));
|
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Rio)", "Rio", "", true, "DUMBUUIDC"));
|
||||||
EventBase newEvent = new EventBaseImpl("Extreme Sailing Series 2013 (Muscat)", "Muscat", "", true, "FIXUUID");
|
EventBase newEvent = new EventBaseImpl("Extreme Sailing Series 2013 (Muscat)", "Muscat", "", true, "FIXUUID");
|
||||||
@@ -59,11 +66,8 @@ public class OfflineDataManager extends DataManager {
|
|||||||
|
|
||||||
SeriesWithRows qualifying = new SeriesWithRowsImpl("Qualifying", false, null);
|
SeriesWithRows qualifying = new SeriesWithRowsImpl("Qualifying", false, null);
|
||||||
SeriesWithRows medal = new SeriesWithRowsImpl("Medal", true, null);
|
SeriesWithRows medal = new SeriesWithRowsImpl("Medal", true, null);
|
||||||
RaceGroup raceGroup = new RaceGroupImpl(
|
RaceGroup raceGroup = new RaceGroupImpl("ESS", new BoatClassImpl("X40", false), null, Arrays.asList(qualifying,
|
||||||
"ESS",
|
medal));
|
||||||
new BoatClassImpl("X40", false),
|
|
||||||
null,
|
|
||||||
Arrays.asList(qualifying, medal));
|
|
||||||
|
|
||||||
List<Competitor> competitors = new ArrayList<Competitor>();
|
List<Competitor> competitors = new ArrayList<Competitor>();
|
||||||
competitors.add(new CompetitorImpl(UUID.randomUUID(), "SAP Extreme Sailing Team", null, null));
|
competitors.add(new CompetitorImpl(UUID.randomUUID(), "SAP Extreme Sailing Team", null, null));
|
||||||
@@ -74,66 +78,39 @@ public class OfflineDataManager extends DataManager {
|
|||||||
|
|
||||||
RaceLogEventFactory factory = new RaceLogEventFactoryImpl();
|
RaceLogEventFactory factory = new RaceLogEventFactoryImpl();
|
||||||
RaceLog log = new RaceLogImpl(UUID.randomUUID());
|
RaceLog log = new RaceLogImpl(UUID.randomUUID());
|
||||||
log.add(factory.createStartTimeEvent(
|
log.add(factory.createStartTimeEvent(new MillisecondsTimePoint(new Date().getTime() - 2000), 1,
|
||||||
new MillisecondsTimePoint(new Date().getTime() - 2000),
|
|
||||||
1,
|
|
||||||
new MillisecondsTimePoint(new Date().getTime() - 1000)));
|
new MillisecondsTimePoint(new Date().getTime() - 1000)));
|
||||||
|
|
||||||
log.add(factory.createRaceStatusEvent(
|
log.add(factory.createRaceStatusEvent(new MillisecondsTimePoint(new Date().getTime()), 1,
|
||||||
new MillisecondsTimePoint(new Date().getTime()),
|
|
||||||
1,
|
|
||||||
RaceLogRaceStatus.FINISHING));
|
RaceLogRaceStatus.FINISHING));
|
||||||
|
|
||||||
ManagedRace q1 = new ManagedRaceImpl(
|
ManagedRace q1 = new ManagedRaceImpl(new ManagedRaceIdentifierImpl("A.B", new FleetImpl("A"), qualifying,
|
||||||
new ManagedRaceIdentifierImpl(
|
raceGroup), StartProcedureType.ESS, log);
|
||||||
"Q1",
|
|
||||||
new FleetImpl("Default"),
|
|
||||||
qualifying,
|
|
||||||
raceGroup),
|
|
||||||
StartProcedureType.ESS,
|
|
||||||
log);
|
|
||||||
|
|
||||||
log = new RaceLogImpl(UUID.randomUUID());
|
log = new RaceLogImpl(UUID.randomUUID());
|
||||||
/*log.add(factory.createStartTimeEvent(
|
/*
|
||||||
new MillisecondsTimePoint(new Date()),
|
* log.add(factory.createStartTimeEvent( new MillisecondsTimePoint(new Date()), 1, RaceLogRaceStatus.SCHEDULED,
|
||||||
1,
|
* new MillisecondsTimePoint(new Date().getTime() + 100000)));
|
||||||
RaceLogRaceStatus.SCHEDULED,
|
|
||||||
new MillisecondsTimePoint(new Date().getTime() + 100000)));
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ManagedRace q2 = new ManagedRaceImpl(
|
ManagedRace q2 = new ManagedRaceImpl(new ManagedRaceIdentifierImpl("B", new FleetImpl("A.A"), qualifying,
|
||||||
new ManagedRaceIdentifierImpl(
|
raceGroup), StartProcedureType.ESS, log);
|
||||||
"Q2",
|
|
||||||
new FleetImpl("Default"),
|
|
||||||
qualifying,
|
|
||||||
raceGroup),
|
|
||||||
StartProcedureType.ESS,
|
|
||||||
log);
|
|
||||||
|
|
||||||
log = new RaceLogImpl(UUID.randomUUID());
|
log = new RaceLogImpl(UUID.randomUUID());
|
||||||
/*log.add(factory.createRaceStatusEvent(
|
/*
|
||||||
new MillisecondsTimePoint(new Date()),
|
* log.add(factory.createRaceStatusEvent( new MillisecondsTimePoint(new Date()), 5,
|
||||||
5,
|
* RaceLogRaceStatus.FINISHED));
|
||||||
RaceLogRaceStatus.FINISHED));*/
|
*/
|
||||||
ManagedRace q3 = new ManagedRaceImpl(
|
ManagedRace q3 = new ManagedRaceImpl(new ManagedRaceIdentifierImpl("Q3", new FleetImpl("Default"), qualifying,
|
||||||
new ManagedRaceIdentifierImpl(
|
raceGroup), StartProcedureType.ESS, log);
|
||||||
"Q3",
|
/*
|
||||||
new FleetImpl("Default"),
|
* ManagedRace m1 = new ManagedRaceImpl( new ManagedRaceIdentifierImpl( "M1", new FleetImpl("Default"), medal,
|
||||||
qualifying,
|
* raceGroup), null);
|
||||||
raceGroup),
|
*/
|
||||||
StartProcedureType.ESS,
|
|
||||||
log);
|
|
||||||
/*ManagedRace m1 = new ManagedRaceImpl(
|
|
||||||
new ManagedRaceIdentifierImpl(
|
|
||||||
"M1",
|
|
||||||
new FleetImpl("Default"),
|
|
||||||
medal,
|
|
||||||
raceGroup),
|
|
||||||
null);*/
|
|
||||||
dataStore.addRace(q1);
|
dataStore.addRace(q1);
|
||||||
dataStore.addRace(q2);
|
dataStore.addRace(q2);
|
||||||
dataStore.addRace(q3);
|
dataStore.addRace(q3);
|
||||||
//dataStore.addRace(m1);
|
// dataStore.addRace(m1);
|
||||||
|
|
||||||
Mark m1 = new MarkImpl("Red");
|
Mark m1 = new MarkImpl("Red");
|
||||||
Mark m2 = new MarkImpl("Green");
|
Mark m2 = new MarkImpl("Green");
|
||||||
@@ -144,33 +121,74 @@ public class OfflineDataManager extends DataManager {
|
|||||||
dataStore.addMark(m3);
|
dataStore.addMark(m3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadEvents(LoadClient<Collection<EventBase>> client) {
|
@Override
|
||||||
client.onLoadSucceded(dataStore.getEvents());
|
public LoaderCallbacks<DataLoaderResult<Collection<EventBase>>> createEventsLoader(
|
||||||
|
LoadClient<Collection<EventBase>> callback) {
|
||||||
|
return new ImmediateDataLoaderCallbacks<Collection<EventBase>>(context, callback,
|
||||||
|
new Callable<Collection<EventBase>>() {
|
||||||
|
@Override
|
||||||
|
public Collection<EventBase> call() throws Exception {
|
||||||
|
return dataStore.getEvents();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
public void loadCourseAreas(Serializable parentEventId,
|
|
||||||
LoadClient<Collection<CourseArea>> client) {
|
|
||||||
client.onLoadSucceded(dataStore.getCourseAreas(dataStore.getEvent(parentEventId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadRaces(Serializable courseAreaId,
|
|
||||||
LoadClient<Collection<ManagedRace>> client) {
|
|
||||||
client.onLoadSucceded(dataStore.getRaces());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadMarks(ManagedRace managedRace, LoadClient<Collection<Mark>> client) {
|
public LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(
|
||||||
client.onLoadSucceded(dataStore.getMarks());
|
final Serializable parentEventId, LoadClient<Collection<CourseArea>> callback) {
|
||||||
|
return new ImmediateDataLoaderCallbacks<Collection<CourseArea>>(context, callback,
|
||||||
|
new Callable<Collection<CourseArea>>() {
|
||||||
|
@Override
|
||||||
|
public Collection<CourseArea> call() throws Exception {
|
||||||
|
return dataStore.getCourseAreas(dataStore.getEvent(parentEventId));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadCourse(ManagedRace managedRace, LoadClient<CourseBase> client) {
|
public LoaderCallbacks<DataLoaderResult<Collection<ManagedRace>>> createRacesLoader(Serializable courseAreaId,
|
||||||
client.onLoadSucceded(managedRace.getCourseOnServer());
|
LoadClient<Collection<ManagedRace>> callback) {
|
||||||
|
return new ImmediateDataLoaderCallbacks<Collection<ManagedRace>>(context, callback,
|
||||||
|
new Callable<Collection<ManagedRace>>() {
|
||||||
|
@Override
|
||||||
|
public Collection<ManagedRace> call() throws Exception {
|
||||||
|
return dataStore.getRaces();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadCompetitors(ManagedRace managedRace, LoadClient<Collection<Competitor>> client) {
|
public LoaderCallbacks<DataLoaderResult<Collection<Mark>>> createMarksLoader(ManagedRace managedRace,
|
||||||
client.onLoadSucceded((Collection<Competitor>) managedRace.getCompetitors());
|
LoadClient<Collection<Mark>> callback) {
|
||||||
|
return new ImmediateDataLoaderCallbacks<Collection<Mark>>(context, callback, new Callable<Collection<Mark>>() {
|
||||||
|
@Override
|
||||||
|
public Collection<Mark> call() throws Exception {
|
||||||
|
return dataStore.getMarks();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoaderCallbacks<DataLoaderResult<CourseBase>> createCourseLoader(final ManagedRace managedRace,
|
||||||
|
LoadClient<CourseBase> callback) {
|
||||||
|
return new ImmediateDataLoaderCallbacks<CourseBase>(context, callback, new Callable<CourseBase>() {
|
||||||
|
@Override
|
||||||
|
public CourseBase call() throws Exception {
|
||||||
|
return managedRace.getCourseOnServer();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<Competitor>>> createCompetitorsLoader(
|
||||||
|
final ManagedRace managedRace, LoadClient<Collection<Competitor>> callback) {
|
||||||
|
return new ImmediateDataLoaderCallbacks<Collection<Competitor>>(context, callback,
|
||||||
|
new Callable<Collection<Competitor>>() {
|
||||||
|
@Override
|
||||||
|
public Collection<Competitor> call() throws Exception {
|
||||||
|
return managedRace.getCompetitors();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+117
-130
@@ -1,13 +1,15 @@
|
|||||||
package com.sap.sailing.racecommittee.app.data;
|
package com.sap.sailing.racecommittee.app.data;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.MalformedURLException;
|
import java.net.URL;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import android.app.LoaderManager.LoaderCallbacks;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Loader;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
@@ -19,14 +21,18 @@ import com.sap.sailing.domain.base.SharedDomainFactory;
|
|||||||
import com.sap.sailing.racecommittee.app.AppPreferences;
|
import com.sap.sailing.racecommittee.app.AppPreferences;
|
||||||
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
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.CompetitorsDataHandler;
|
||||||
import com.sap.sailing.racecommittee.app.data.handlers.CourseDataHandler;
|
import com.sap.sailing.racecommittee.app.data.handlers.CourseBaseHandler;
|
||||||
import com.sap.sailing.racecommittee.app.data.handlers.DataHandler;
|
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.EventsDataHandler;
|
||||||
import com.sap.sailing.racecommittee.app.data.handlers.ManagedRacesDataHandler;
|
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.handlers.MarksDataHandler;
|
||||||
import com.sap.sailing.racecommittee.app.data.loaders.DataLoader;
|
import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderCallbacks;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderCallbacks.LoaderCreator;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderResult;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.ImmediateDataLoaderCallbacks;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.OnlineDataLoader;
|
||||||
import com.sap.sailing.racecommittee.app.data.parsers.CompetitorsDataParser;
|
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.CourseBaseParser;
|
||||||
import com.sap.sailing.racecommittee.app.data.parsers.DataParser;
|
import com.sap.sailing.racecommittee.app.data.parsers.DataParser;
|
||||||
import com.sap.sailing.racecommittee.app.data.parsers.EventsDataParser;
|
import com.sap.sailing.racecommittee.app.data.parsers.EventsDataParser;
|
||||||
import com.sap.sailing.racecommittee.app.data.parsers.ManagedRacesDataParser;
|
import com.sap.sailing.racecommittee.app.data.parsers.ManagedRacesDataParser;
|
||||||
@@ -34,9 +40,10 @@ import com.sap.sailing.racecommittee.app.data.parsers.MarksDataParser;
|
|||||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
|
||||||
import com.sap.sailing.racecommittee.app.domain.impl.DomainFactoryImpl;
|
import com.sap.sailing.racecommittee.app.domain.impl.DomainFactoryImpl;
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.ControlPointDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.ControlPointDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseDataDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseBaseDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.GateDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.GateDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.MarkDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.MarkDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDeserializer;
|
||||||
@@ -58,25 +65,10 @@ import com.sap.sailing.server.gateway.deserialization.racelog.impl.RaceLogEventD
|
|||||||
* Enables accessing of data.
|
* Enables accessing of data.
|
||||||
*/
|
*/
|
||||||
public class OnlineDataManager extends DataManager {
|
public class OnlineDataManager extends DataManager {
|
||||||
// private static final String TAG = OnlineDataManager.class.getName();
|
private static final String TAG = OnlineDataManager.class.getName();
|
||||||
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
OnlineDataManager(Context context, DataStore dataStore) {
|
OnlineDataManager(Context context, DataStore dataStore) {
|
||||||
super(dataStore);
|
super(context, dataStore);
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadEvents(LoadClient<Collection<EventBase>> client) {
|
|
||||||
if (dataStore.getEvents().isEmpty()) {
|
|
||||||
reloadEvents(client);
|
|
||||||
} else {
|
|
||||||
client.onLoadSucceded(dataStore.getEvents());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEvents(Collection<EventBase> events) {
|
public void addEvents(Collection<EventBase> events) {
|
||||||
@@ -85,89 +77,88 @@ public class OnlineDataManager extends DataManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reloadEvents(LoadClient<Collection<EventBase>> client) {
|
|
||||||
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
|
||||||
DataParser<Collection<EventBase>> parser = new EventsDataParser(new EventBaseJsonDeserializer(
|
|
||||||
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(domainFactory))));
|
|
||||||
DataHandler<Collection<EventBase>> handler = new EventsDataHandler(this, client);
|
|
||||||
|
|
||||||
try {
|
|
||||||
new DataLoader<Collection<EventBase>>(context, URI.create(AppPreferences.getServerBaseURL(context)
|
|
||||||
+ "/sailingserver/events"), parser, handler).forceLoad();
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadCourseAreas(final Serializable parentEventId, final LoadClient<Collection<CourseArea>> client) {
|
|
||||||
|
|
||||||
if (dataStore.hasEvent(parentEventId)) {
|
|
||||||
EventBase event = dataStore.getEvent(parentEventId);
|
|
||||||
client.onLoadSucceded(dataStore.getCourseAreas(event));
|
|
||||||
} else {
|
|
||||||
reloadEvents(new LoadClient<Collection<EventBase>>() {
|
|
||||||
public void onLoadSucceded(Collection<EventBase> data) {
|
|
||||||
if (dataStore.hasEvent(parentEventId)) {
|
|
||||||
EventBase 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<ManagedRace> data) {
|
public void addRaces(Collection<ManagedRace> data) {
|
||||||
for (ManagedRace race : data) {
|
for (ManagedRace race : data) {
|
||||||
dataStore.addRace(race);
|
dataStore.addRace(race);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadRaces(Serializable courseAreaId, LoadClient<Collection<ManagedRace>> client) {
|
|
||||||
if (!dataStore.hasCourseArea(courseAreaId)) {
|
|
||||||
client.onLoadFailed(new DataLoadingException(String.format("No course area found with id %s", courseAreaId)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
|
||||||
JsonDeserializer<BoatClass> boatClassDeserializer = new BoatClassJsonDeserializer(domainFactory);
|
|
||||||
DataParser<Collection<ManagedRace>> parser = new ManagedRacesDataParser(context, new RaceGroupDeserializer(
|
|
||||||
boatClassDeserializer, new SeriesWithRowsDeserializer(new RaceRowDeserializer(new FleetDeserializer(
|
|
||||||
new ColorDeserializer()), new RaceCellDeserializer(
|
|
||||||
new RaceLogDeserializer(RaceLogEventDeserializer.create(domainFactory)))))));
|
|
||||||
DataHandler<Collection<ManagedRace>> handler = new ManagedRacesDataHandler(this, client);
|
|
||||||
try {
|
|
||||||
new DataLoader<Collection<ManagedRace>>(context, URI.create(AppPreferences.getServerBaseURL(context)
|
|
||||||
+ "/sailingserver/rc/racegroups?courseArea=" + courseAreaId.toString()), parser, handler)
|
|
||||||
.forceLoad();
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMarks(Collection<Mark> marks) {
|
public void addMarks(Collection<Mark> marks) {
|
||||||
for (Mark mark : marks) {
|
for (Mark mark : marks) {
|
||||||
dataStore.addMark(mark);
|
dataStore.addMark(mark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadMarks(ManagedRace managedRace, LoadClient<Collection<Mark>> client) {
|
@Override
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<EventBase>>> createEventsLoader(
|
||||||
|
LoadClient<Collection<EventBase>> callback) {
|
||||||
|
return new DataLoaderCallbacks<Collection<EventBase>>(callback, new LoaderCreator<Collection<EventBase>>() {
|
||||||
|
@Override
|
||||||
|
public Loader<DataLoaderResult<Collection<EventBase>>> create(int id, Bundle args) throws Exception {
|
||||||
|
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
||||||
|
DataParser<Collection<EventBase>> parser = new EventsDataParser(new EventBaseJsonDeserializer(
|
||||||
|
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(domainFactory))));
|
||||||
|
DataHandler<Collection<EventBase>> handler = new EventsDataHandler(OnlineDataManager.this);
|
||||||
|
|
||||||
|
ExLog.i(TAG, "getEventsLoader created new loader...");
|
||||||
|
|
||||||
|
return new OnlineDataLoader<Collection<EventBase>>(context, new URL(AppPreferences
|
||||||
|
.getServerBaseURL(context) + "/sailingserver/events"), parser, handler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(
|
||||||
|
final Serializable parentEventId, LoadClient<Collection<CourseArea>> callback) {
|
||||||
|
return new ImmediateDataLoaderCallbacks<Collection<CourseArea>>(context, callback,
|
||||||
|
new Callable<Collection<CourseArea>>() {
|
||||||
|
@Override
|
||||||
|
public Collection<CourseArea> call() throws Exception {
|
||||||
|
if (dataStore.hasEvent(parentEventId)) {
|
||||||
|
EventBase event = dataStore.getEvent(parentEventId);
|
||||||
|
return dataStore.getCourseAreas(event);
|
||||||
|
} else {
|
||||||
|
throw new DataLoadingException(String.format(
|
||||||
|
"Unable to load course areas for unknown event %s.", parentEventId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<ManagedRace>>> createRacesLoader(final Serializable courseAreaId,
|
||||||
|
LoadClient<Collection<ManagedRace>> callback) {
|
||||||
|
return new DataLoaderCallbacks<Collection<ManagedRace>>(callback, new LoaderCreator<Collection<ManagedRace>>() {
|
||||||
|
@Override
|
||||||
|
public Loader<DataLoaderResult<Collection<ManagedRace>>> create(int id, Bundle args) throws Exception {
|
||||||
|
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
||||||
|
JsonDeserializer<BoatClass> boatClassDeserializer = new BoatClassJsonDeserializer(domainFactory);
|
||||||
|
DataParser<Collection<ManagedRace>> parser = new ManagedRacesDataParser(context,
|
||||||
|
new RaceGroupDeserializer(boatClassDeserializer, new SeriesWithRowsDeserializer(
|
||||||
|
new RaceRowDeserializer(new FleetDeserializer(new ColorDeserializer()),
|
||||||
|
new RaceCellDeserializer(new RaceLogDeserializer(
|
||||||
|
RaceLogEventDeserializer.create(domainFactory)))))));
|
||||||
|
DataHandler<Collection<ManagedRace>> handler = new ManagedRacesDataHandler(OnlineDataManager.this);
|
||||||
|
|
||||||
|
return new OnlineDataLoader<Collection<ManagedRace>>(context, new URL(AppPreferences
|
||||||
|
.getServerBaseURL(context)
|
||||||
|
+ "/sailingserver/rc/racegroups?courseArea="
|
||||||
|
+ courseAreaId.toString()), parser, handler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<Mark>>> createMarksLoader(final ManagedRace managedRace,
|
||||||
|
LoadClient<Collection<Mark>> callback) {
|
||||||
|
return new DataLoaderCallbacks<Collection<Mark>>(callback, new LoaderCreator<Collection<Mark>>() {
|
||||||
|
@Override
|
||||||
|
public Loader<DataLoaderResult<Collection<Mark>>> create(int id, Bundle args) throws Exception {
|
||||||
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
||||||
JsonDeserializer<Mark> markDeserializer = new MarkDeserializer(domainFactory);
|
JsonDeserializer<Mark> markDeserializer = new MarkDeserializer(domainFactory);
|
||||||
DataParser<Collection<Mark>> parser = new MarksDataParser(markDeserializer);
|
DataParser<Collection<Mark>> parser = new MarksDataParser(markDeserializer);
|
||||||
DataHandler<Collection<Mark>> handler = new MarksDataHandler(this, client);
|
DataHandler<Collection<Mark>> handler = new MarksDataHandler(OnlineDataManager.this);
|
||||||
|
|
||||||
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
|
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
|
||||||
|
|
||||||
@@ -175,29 +166,27 @@ public class OnlineDataManager extends DataManager {
|
|||||||
String raceColumnName = URLEncoder.encode(identifier.getRaceName());
|
String raceColumnName = URLEncoder.encode(identifier.getRaceName());
|
||||||
String fleetName = URLEncoder.encode(identifier.getFleet().getName());
|
String fleetName = URLEncoder.encode(identifier.getFleet().getName());
|
||||||
|
|
||||||
try {
|
return new OnlineDataLoader<Collection<Mark>>(context, new URL(AppPreferences
|
||||||
new DataLoader<Collection<Mark>>(context, URI.create(AppPreferences.getServerBaseURL(context)
|
.getServerBaseURL(context)
|
||||||
+ "/sailingserver/rc/marks?leaderboard=" + raceGroupName + "&raceColumn=" + raceColumnName
|
+ "/sailingserver/rc/marks?leaderboard="
|
||||||
+ "&fleet=" + fleetName), parser, handler)
|
+ raceGroupName
|
||||||
.forceLoad();
|
+ "&raceColumn=" + raceColumnName + "&fleet=" + fleetName), parser, handler);
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadCourse(ManagedRace managedRace, LoadClient<CourseBase> client) {
|
public LoaderCallbacks<DataLoaderResult<CourseBase>> createCourseLoader(final ManagedRace managedRace,
|
||||||
|
LoadClient<CourseBase> callback) {
|
||||||
|
return new DataLoaderCallbacks<CourseBase>(callback, new LoaderCreator<CourseBase>() {
|
||||||
|
@Override
|
||||||
|
public Loader<DataLoaderResult<CourseBase>> create(int id, Bundle args) throws Exception {
|
||||||
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
||||||
JsonDeserializer<CourseBase> courseBaseDeserializer = new CourseDataDeserializer(
|
JsonDeserializer<CourseBase> courseBaseDeserializer = new CourseBaseDeserializer(
|
||||||
new WaypointDeserializer(
|
new WaypointDeserializer(new ControlPointDeserializer(new MarkDeserializer(domainFactory),
|
||||||
new ControlPointDeserializer(
|
new GateDeserializer(domainFactory, new MarkDeserializer(domainFactory)))));
|
||||||
new MarkDeserializer(domainFactory),
|
DataParser<CourseBase> parser = new CourseBaseParser(courseBaseDeserializer);
|
||||||
new GateDeserializer(domainFactory,
|
DataHandler<CourseBase> handler = new CourseBaseHandler(OnlineDataManager.this, managedRace);
|
||||||
new MarkDeserializer(domainFactory)))));
|
|
||||||
DataParser<CourseBase> parser = new CourseDataParser(courseBaseDeserializer);
|
|
||||||
DataHandler<CourseBase> handler = new CourseDataHandler(this, client, managedRace);
|
|
||||||
|
|
||||||
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
|
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
|
||||||
|
|
||||||
@@ -205,24 +194,25 @@ public class OnlineDataManager extends DataManager {
|
|||||||
String raceColumnName = URLEncoder.encode(identifier.getRaceName());
|
String raceColumnName = URLEncoder.encode(identifier.getRaceName());
|
||||||
String fleetName = URLEncoder.encode(identifier.getFleet().getName());
|
String fleetName = URLEncoder.encode(identifier.getFleet().getName());
|
||||||
|
|
||||||
try {
|
return new OnlineDataLoader<CourseBase>(context, new URL(AppPreferences.getServerBaseURL(context)
|
||||||
new DataLoader<CourseBase>(context, URI.create(AppPreferences.getServerBaseURL(context)
|
+ "/sailingserver/rc/currentcourse?leaderboard=" + raceGroupName + "&raceColumn="
|
||||||
+ "/sailingserver/rc/currentcourse?leaderboard=" + raceGroupName + "&raceColumn=" + raceColumnName
|
+ raceColumnName + "&fleet=" + fleetName), parser, handler);
|
||||||
+ "&fleet=" + fleetName), parser, handler)
|
|
||||||
.forceLoad();
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadCompetitors(ManagedRace managedRace, LoadClient<Collection<Competitor>> client) {
|
public LoaderCallbacks<DataLoaderResult<Collection<Competitor>>> createCompetitorsLoader(
|
||||||
|
final ManagedRace managedRace, LoadClient<Collection<Competitor>> callback) {
|
||||||
|
return new DataLoaderCallbacks<Collection<Competitor>>(callback, new LoaderCreator<Collection<Competitor>>() {
|
||||||
|
@Override
|
||||||
|
public Loader<DataLoaderResult<Collection<Competitor>>> create(int id, Bundle args) throws Exception {
|
||||||
|
ExLog.i(TAG, String.format("Creating Competitor-OnlineDataLoader %d", id));
|
||||||
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
|
||||||
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorDeserializer(domainFactory);
|
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorDeserializer(domainFactory);
|
||||||
DataParser<Collection<Competitor>> parser = new CompetitorsDataParser(competitorDeserializer);
|
DataParser<Collection<Competitor>> parser = new CompetitorsDataParser(competitorDeserializer);
|
||||||
DataHandler<Collection<Competitor>> handler = new CompetitorsDataHandler(this, client, managedRace);
|
DataHandler<Collection<Competitor>> handler = new CompetitorsDataHandler(OnlineDataManager.this,
|
||||||
|
managedRace);
|
||||||
|
|
||||||
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
|
ManagedRaceIdentifier identifier = managedRace.getIdentifier();
|
||||||
|
|
||||||
@@ -230,15 +220,12 @@ public class OnlineDataManager extends DataManager {
|
|||||||
String raceColumnName = URLEncoder.encode(identifier.getRaceName());
|
String raceColumnName = URLEncoder.encode(identifier.getRaceName());
|
||||||
String fleetName = URLEncoder.encode(identifier.getFleet().getName());
|
String fleetName = URLEncoder.encode(identifier.getFleet().getName());
|
||||||
|
|
||||||
try {
|
return new OnlineDataLoader<Collection<Competitor>>(context, new URL(AppPreferences
|
||||||
new DataLoader<Collection<Competitor>>(context, URI.create(AppPreferences.getServerBaseURL(context)
|
.getServerBaseURL(context)
|
||||||
+ "/sailingserver/rc/competitors?leaderboard=" + raceGroupName + "&raceColumn=" + raceColumnName
|
+ "/sailingserver/rc/competitors?leaderboard="
|
||||||
+ "&fleet=" + fleetName), parser, handler)
|
+ raceGroupName
|
||||||
.forceLoad();
|
+ "&raceColumn=" + raceColumnName + "&fleet=" + fleetName), parser, handler);
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+97
-6
@@ -3,27 +3,118 @@ package com.sap.sailing.racecommittee.app.data;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import android.app.LoaderManager;
|
||||||
|
import android.app.LoaderManager.LoaderCallbacks;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.CourseArea;
|
import com.sap.sailing.domain.base.CourseArea;
|
||||||
import com.sap.sailing.domain.base.CourseBase;
|
import com.sap.sailing.domain.base.CourseBase;
|
||||||
import com.sap.sailing.domain.base.EventBase;
|
import com.sap.sailing.domain.base.EventBase;
|
||||||
import com.sap.sailing.domain.base.Mark;
|
import com.sap.sailing.domain.base.Mark;
|
||||||
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderResult;
|
||||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Interface for everything read related when working with data.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The result values of this interface's methods are meant to be used in conjunction with the Android's
|
||||||
|
* {@link LoaderManager} facility. Everything that is loaded by this interface is stored and cached in the underlying
|
||||||
|
* {@link DataStore}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If there are cached results your {@link LoadClient}'s callback methods might be called twice (first cached results;
|
||||||
|
* afterwards remote results). See {@link LoadClient} for restrictions that apply to your data handling code.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
public interface ReadonlyDataManager {
|
public interface ReadonlyDataManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the underlying data store.
|
||||||
|
*
|
||||||
|
* @return the {@link DataStore}.
|
||||||
|
*/
|
||||||
public DataStore getDataStore();
|
public DataStore getDataStore();
|
||||||
|
|
||||||
public void loadEvents(LoadClient<Collection<EventBase>> client);
|
/**
|
||||||
|
* Creates a new {@link LoaderCallbacks} object for loading {@link EventBase}s.
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* {@link LoadClient} implementing your data handling code.
|
||||||
|
* @return {@link LoaderCallbacks} to be used in
|
||||||
|
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
|
||||||
|
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
|
||||||
|
*/
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<EventBase>>> createEventsLoader(
|
||||||
|
LoadClient<Collection<EventBase>> callback);
|
||||||
|
|
||||||
public void loadCourseAreas(Serializable parentEventId, LoadClient<Collection<CourseArea>> client);
|
/**
|
||||||
|
* Creates a new {@link LoaderCallbacks} object for loading {@link CourseArea}s.
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* {@link LoadClient} implementing your data handling code.
|
||||||
|
* @return {@link LoaderCallbacks} to be used in
|
||||||
|
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
|
||||||
|
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
|
||||||
|
*/
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createCourseAreasLoader(
|
||||||
|
Serializable parentEventId, LoadClient<Collection<CourseArea>> callback);
|
||||||
|
|
||||||
public void loadRaces(Serializable courseAreaId, LoadClient<Collection<ManagedRace>> client);
|
/**
|
||||||
|
* Creates a new {@link LoaderCallbacks} object for loading {@link ManagedRace}s of a specific {@link CourseArea}.
|
||||||
|
*
|
||||||
|
* @param courseAreaId
|
||||||
|
* the {@link CourseArea}'s Identifier.
|
||||||
|
* @param callback
|
||||||
|
* {@link LoadClient} implementing your data handling code.
|
||||||
|
* @return {@link LoaderCallbacks} to be used in
|
||||||
|
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
|
||||||
|
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
|
||||||
|
*/
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<ManagedRace>>> createRacesLoader(Serializable courseAreaId,
|
||||||
|
LoadClient<Collection<ManagedRace>> callback);
|
||||||
|
|
||||||
public void loadMarks(ManagedRace managedRace, LoadClient<Collection<Mark>> client);
|
/**
|
||||||
|
* Creates a new {@link LoaderCallbacks} object for loading a race's {@link Mark}s.
|
||||||
|
*
|
||||||
|
* @param managedRace
|
||||||
|
* the {@link ManagedRace}.
|
||||||
|
* @param callback
|
||||||
|
* {@link LoadClient} implementing your data handling code.
|
||||||
|
* @return {@link LoaderCallbacks} to be used in
|
||||||
|
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
|
||||||
|
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
|
||||||
|
*/
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<Mark>>> createMarksLoader(ManagedRace managedRace,
|
||||||
|
LoadClient<Collection<Mark>> callback);
|
||||||
|
|
||||||
public void loadCourse(ManagedRace managedRace, LoadClient<CourseBase> client);
|
/**
|
||||||
|
* Creates a new {@link LoaderCallbacks} object for loading a race's {@link CourseBase}.
|
||||||
|
*
|
||||||
|
* @param managedRace
|
||||||
|
* the {@link ManagedRace}.
|
||||||
|
* @param callback
|
||||||
|
* {@link LoadClient} implementing your data handling code.
|
||||||
|
* @return {@link LoaderCallbacks} to be used in
|
||||||
|
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
|
||||||
|
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
|
||||||
|
*/
|
||||||
|
public LoaderCallbacks<DataLoaderResult<CourseBase>> createCourseLoader(ManagedRace managedRace,
|
||||||
|
LoadClient<CourseBase> callback);
|
||||||
|
|
||||||
public void loadCompetitors(ManagedRace managedRace, LoadClient<Collection<Competitor>> client);
|
/**
|
||||||
|
* Creates a new {@link LoaderCallbacks} object for loading {@link Competitor}s.
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* {@link LoadClient} implementing your data handling code.
|
||||||
|
* @return {@link LoaderCallbacks} to be used in
|
||||||
|
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
|
||||||
|
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
|
||||||
|
*/
|
||||||
|
public LoaderCallbacks<DataLoaderResult<Collection<Competitor>>> createCompetitorsLoader(ManagedRace managedRace,
|
||||||
|
LoadClient<Collection<Competitor>> callback);
|
||||||
}
|
}
|
||||||
+28
-1
@@ -1,6 +1,33 @@
|
|||||||
package com.sap.sailing.racecommittee.app.data.clients;
|
package com.sap.sailing.racecommittee.app.data.clients;
|
||||||
|
|
||||||
|
import android.app.LoaderManager.LoaderCallbacks;
|
||||||
|
import android.content.Loader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to hide complexity of {@link LoaderCallbacks#onLoadFinished(Loader, Object)}. Keep in mind that all
|
||||||
|
* restrictions that apply on the LoaderCallback's method also apply to all methods of this interface.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* loaded data type.
|
||||||
|
*/
|
||||||
public interface LoadClient<T> {
|
public interface LoadClient<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a {@link Loader} returned a failure to its {@link LoaderCallbacks#onLoadFinished(Loader, Object)}.
|
||||||
|
*
|
||||||
|
* @param reason
|
||||||
|
* the loading has failed.
|
||||||
|
*/
|
||||||
public void onLoadFailed(Exception reason);
|
public void onLoadFailed(Exception reason);
|
||||||
public void onLoadSucceded(T data);
|
|
||||||
|
/**
|
||||||
|
* Called when a {@link Loader} returned successfully to its {@link LoaderCallbacks#onLoadFinished(Loader, Object)}.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* that was loaded.
|
||||||
|
* @param isCached
|
||||||
|
* <code>true</code> if returned data is cached data.
|
||||||
|
*/
|
||||||
|
public void onLoadSucceded(T data, boolean isCached);
|
||||||
|
|
||||||
}
|
}
|
||||||
+13
-5
@@ -4,21 +4,29 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
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;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
|
|
||||||
public class CompetitorsDataHandler extends DataHandler<Collection<Competitor>> {
|
public class CompetitorsDataHandler extends DataHandler<Collection<Competitor>> {
|
||||||
|
|
||||||
private ManagedRace race;
|
private ManagedRace race;
|
||||||
|
|
||||||
public CompetitorsDataHandler(OnlineDataManager manager, LoadClient<Collection<Competitor>> client, ManagedRace managedRace) {
|
public CompetitorsDataHandler(OnlineDataManager manager, ManagedRace managedRace) {
|
||||||
super(manager, client);
|
super(manager);
|
||||||
race = managedRace;
|
race = managedRace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaded(Collection<Competitor> data) {
|
public boolean hasCachedResults() {
|
||||||
super.onLoaded(data);
|
return race.getCompetitors() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Competitor> getCachedResults() {
|
||||||
|
return race.getCompetitors();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(Collection<Competitor> data) {
|
||||||
race.setCompetitors(data);
|
race.setCompetitors(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.data.handlers;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.CourseBase;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
||||||
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
|
|
||||||
|
public class CourseBaseHandler extends DataHandler<CourseBase> {
|
||||||
|
|
||||||
|
private ManagedRace race;
|
||||||
|
|
||||||
|
public CourseBaseHandler(OnlineDataManager manager, ManagedRace managedRace) {
|
||||||
|
super(manager);
|
||||||
|
race = managedRace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasCachedResults() {
|
||||||
|
return race.getCourseOnServer() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CourseBase getCachedResults() {
|
||||||
|
return race.getCourseOnServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(CourseBase data) {
|
||||||
|
race.setCourseOnServer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
package com.sap.sailing.racecommittee.app.data.handlers;
|
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.CourseBase;
|
|
||||||
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 CourseDataHandler extends DataHandler<CourseBase> {
|
|
||||||
|
|
||||||
private ManagedRace race;
|
|
||||||
|
|
||||||
public CourseDataHandler(OnlineDataManager manager, LoadClient<CourseBase> client, ManagedRace managedRace) {
|
|
||||||
super(manager, client);
|
|
||||||
race = managedRace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoaded(CourseBase data) {
|
|
||||||
super.onLoaded(data);
|
|
||||||
race.setCourseOnServer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+7
-8
@@ -1,22 +1,21 @@
|
|||||||
package com.sap.sailing.racecommittee.app.data.handlers;
|
package com.sap.sailing.racecommittee.app.data.handlers;
|
||||||
|
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
||||||
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
|
||||||
|
|
||||||
public abstract class DataHandler<T> {
|
public abstract class DataHandler<T> {
|
||||||
protected OnlineDataManager manager;
|
protected OnlineDataManager manager;
|
||||||
protected LoadClient<T> client;
|
|
||||||
|
|
||||||
public DataHandler(OnlineDataManager manager, LoadClient<T> client) {
|
public DataHandler(OnlineDataManager manager) {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
this.client = client;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLoaded(T data) {
|
public abstract void onResult(T data);
|
||||||
client.onLoadSucceded(data);
|
|
||||||
|
public boolean hasCachedResults() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFailed(Exception reason) {
|
public T getCachedResults() {
|
||||||
client.onLoadFailed(reason);
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+13
-5
@@ -4,18 +4,26 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import com.sap.sailing.domain.base.EventBase;
|
import com.sap.sailing.domain.base.EventBase;
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
||||||
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
|
||||||
|
|
||||||
public class EventsDataHandler extends DataHandler<Collection<EventBase>> {
|
public class EventsDataHandler extends DataHandler<Collection<EventBase>> {
|
||||||
|
|
||||||
public EventsDataHandler(OnlineDataManager manager, LoadClient<Collection<EventBase>> client) {
|
public EventsDataHandler(OnlineDataManager manager) {
|
||||||
super(manager, client);
|
super(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaded(Collection<EventBase> data) {
|
public void onResult(Collection<EventBase> data) {
|
||||||
super.onLoaded(data);
|
|
||||||
manager.addEvents(data);
|
manager.addEvents(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasCachedResults() {
|
||||||
|
return !manager.getDataStore().getEvents().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<EventBase> getCachedResults() {
|
||||||
|
return manager.getDataStore().getEvents();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+13
-5
@@ -3,18 +3,26 @@ package com.sap.sailing.racecommittee.app.data.handlers;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
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;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
|
|
||||||
public class ManagedRacesDataHandler extends DataHandler<Collection<ManagedRace>> {
|
public class ManagedRacesDataHandler extends DataHandler<Collection<ManagedRace>> {
|
||||||
|
|
||||||
public ManagedRacesDataHandler(OnlineDataManager manager, LoadClient<Collection<ManagedRace>> client) {
|
public ManagedRacesDataHandler(OnlineDataManager manager) {
|
||||||
super(manager, client);
|
super(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaded(Collection<ManagedRace> data) {
|
public boolean hasCachedResults() {
|
||||||
super.onLoaded(data);
|
return !manager.getDataStore().getRaces().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ManagedRace> getCachedResults() {
|
||||||
|
return manager.getDataStore().getRaces();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(Collection<ManagedRace> data) {
|
||||||
manager.addRaces(data);
|
manager.addRaces(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-5
@@ -4,17 +4,25 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import com.sap.sailing.domain.base.Mark;
|
import com.sap.sailing.domain.base.Mark;
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
||||||
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
|
||||||
|
|
||||||
public class MarksDataHandler extends DataHandler<Collection<Mark>> {
|
public class MarksDataHandler extends DataHandler<Collection<Mark>> {
|
||||||
|
|
||||||
public MarksDataHandler(OnlineDataManager manager, LoadClient<Collection<Mark>> client) {
|
public MarksDataHandler(OnlineDataManager manager) {
|
||||||
super(manager, client);
|
super(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoaded(Collection<Mark> data) {
|
public boolean hasCachedResults() {
|
||||||
super.onLoaded(data);
|
return !manager.getDataStore().getMarks().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Mark> getCachedResults() {
|
||||||
|
return manager.getDataStore().getMarks();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(Collection<Mark> data) {
|
||||||
manager.addMarks(data);
|
manager.addMarks(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -4,17 +4,17 @@ import java.io.BufferedInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.URL;
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
public class HttpGetRequest extends HttpRequest {
|
public class HttpGetRequest extends HttpRequest {
|
||||||
|
|
||||||
public HttpGetRequest(URI requestUri) throws MalformedURLException, IOException {
|
public HttpGetRequest(URL requestUrl) {
|
||||||
super(requestUri.toURL());
|
super(requestUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InputStream execute(HttpURLConnection connection) throws IOException {
|
protected BufferedInputStream execute(HttpURLConnection connection) throws IOException {
|
||||||
return new BufferedInputStream(connection.getInputStream());
|
InputStream stream = connection.getInputStream();
|
||||||
|
return new BufferedInputStream(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-7
@@ -3,11 +3,9 @@ package com.sap.sailing.racecommittee.app.data.http;
|
|||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.URL;
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
public class HttpJsonPostRequest extends HttpRequest {
|
public class HttpJsonPostRequest extends HttpRequest {
|
||||||
@@ -15,14 +13,13 @@ public class HttpJsonPostRequest extends HttpRequest {
|
|||||||
|
|
||||||
private String requestBody;
|
private String requestBody;
|
||||||
|
|
||||||
public HttpJsonPostRequest(URI requestUri, String body) throws MalformedURLException, IOException {
|
public HttpJsonPostRequest(URL requestUrl, String body) {
|
||||||
super(requestUri.toURL());
|
super(requestUrl);
|
||||||
this.requestBody = body;
|
this.requestBody = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InputStream execute(HttpURLConnection connection) throws IOException {
|
protected BufferedInputStream execute(HttpURLConnection connection) throws IOException {
|
||||||
// connection.setDoInput(true);
|
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
connection.setChunkedStreamingMode(0);
|
connection.setChunkedStreamingMode(0);
|
||||||
|
|
||||||
|
|||||||
+24
-13
@@ -1,5 +1,8 @@
|
|||||||
package com.sap.sailing.racecommittee.app.data.http;
|
package com.sap.sailing.racecommittee.app.data.http;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -28,25 +31,24 @@ public abstract class HttpRequest {
|
|||||||
throw new IOException(String.format("Request response had no valid status."));
|
throw new IOException(String.format("Request response had no valid status."));
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpURLConnection connection;
|
private URL url;
|
||||||
|
|
||||||
public HttpRequest(URL url) throws IOException {
|
public HttpRequest(URL url) {
|
||||||
this((HttpURLConnection) url.openConnection());
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpRequest(HttpURLConnection connection) {
|
protected abstract BufferedInputStream execute(HttpURLConnection connection) throws IOException;
|
||||||
this.connection = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract InputStream execute(HttpURLConnection connection) throws IOException;
|
|
||||||
|
|
||||||
public InputStream execute() throws Exception {
|
public InputStream execute() throws Exception {
|
||||||
ExLog.i(TAG, String.format("(Request %d) Executing HTTP request on %s.", this.hashCode(), connection.getURL()));
|
ExLog.i(TAG, String.format("(Request %d) Executing HTTP request on %s.", this.hashCode(), url));
|
||||||
|
|
||||||
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
|
|
||||||
connection.setConnectTimeout(5000);
|
connection.setConnectTimeout(5000);
|
||||||
connection.setReadTimeout(15000);
|
connection.setReadTimeout(15000);
|
||||||
|
connection.setRequestProperty("connection", "close");
|
||||||
|
|
||||||
InputStream stream = null;
|
BufferedInputStream stream = null;
|
||||||
try {
|
try {
|
||||||
stream = execute(connection);
|
stream = execute(connection);
|
||||||
} catch (FileNotFoundException fnfe) {
|
} catch (FileNotFoundException fnfe) {
|
||||||
@@ -55,12 +57,21 @@ public abstract class HttpRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validateHttpResponse(connection);
|
validateHttpResponse(connection);
|
||||||
|
byte[] streamData = copyStream(stream);
|
||||||
|
connection.disconnect();
|
||||||
|
|
||||||
ExLog.i(TAG, String.format("(Request %d) HTTP request executed.", this.hashCode()));
|
ExLog.i(TAG, String.format("(Request %d) HTTP request executed.", this.hashCode()));
|
||||||
return stream;
|
return new ByteArrayInputStream(streamData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
private byte[] copyStream(BufferedInputStream stream) throws IOException {
|
||||||
connection.disconnect();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
int len;
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
while ((len = stream.read(buffer)) != -1) {
|
||||||
|
bos.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
return bos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
-80
@@ -1,80 +0,0 @@
|
|||||||
package com.sap.sailing.racecommittee.app.data.loaders;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
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.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<T> extends AsyncTaskLoader<T> {
|
|
||||||
private static final String TAG = DataLoader.class.getName();
|
|
||||||
|
|
||||||
protected DataParser<T> dataParser;
|
|
||||||
protected DataHandler<T> dataHandler;
|
|
||||||
protected HttpRequest httpRequest;
|
|
||||||
protected volatile Exception lastException;
|
|
||||||
|
|
||||||
public DataLoader(Context context, URI httpGetUri, DataParser<T> dataParser, DataHandler<T> dataHandler)
|
|
||||||
throws MalformedURLException, IOException {
|
|
||||||
this(context, new HttpGetRequest(httpGetUri), dataParser, dataHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataLoader(Context context, HttpRequest request, DataParser<T> dataParser, DataHandler<T> dataHandler) {
|
|
||||||
super(context);
|
|
||||||
this.httpRequest = request;
|
|
||||||
this.dataParser = dataParser;
|
|
||||||
this.dataHandler = dataHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T loadInBackground() {
|
|
||||||
lastException = null;
|
|
||||||
try {
|
|
||||||
return loadDataInBackground();
|
|
||||||
} catch (Exception e) {
|
|
||||||
lastException = e;
|
|
||||||
ExLog.e(TAG, String.format("Exception while loading data:\n%s", e.toString()));
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
|
||||||
PrintWriter stream = new PrintWriter(stringWriter);
|
|
||||||
e.printStackTrace(stream);
|
|
||||||
ExLog.e(TAG, stringWriter.toString());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private T loadDataInBackground() throws Exception {
|
|
||||||
Reader reader = null;
|
|
||||||
try {
|
|
||||||
InputStream inputStream = httpRequest.execute();
|
|
||||||
reader = new InputStreamReader(inputStream);
|
|
||||||
return dataParser.parse(reader);
|
|
||||||
} finally {
|
|
||||||
if (reader != null) {
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
httpRequest.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deliverResult(T data) {
|
|
||||||
if (data == null) {
|
|
||||||
dataHandler.onFailed(lastException);
|
|
||||||
} else {
|
|
||||||
dataHandler.onLoaded(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.data.loaders;
|
||||||
|
|
||||||
|
import android.app.LoaderManager.LoaderCallbacks;
|
||||||
|
import android.content.Loader;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* {@link LoaderCallbacks} wrapper to be used with {@link LoadClient}s.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* On result {@link DataLoaderResult#isSuccessful()} is checked. If true
|
||||||
|
* {@link LoadClient#onLoadSucceded(Object, boolean)} is called; other {@link LoadClient#onLoadFailed(Exception)} is
|
||||||
|
* called.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* There is currently no handling of a {@link Loader}'s reset.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* result type.
|
||||||
|
*/
|
||||||
|
public class DataLoaderCallbacks<T> implements LoaderCallbacks<DataLoaderResult<T>> {
|
||||||
|
private static String TAG = DataLoaderCallbacks.class.getName();
|
||||||
|
|
||||||
|
public interface LoaderCreator<T> {
|
||||||
|
Loader<DataLoaderResult<T>> create(int id, Bundle args) throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoadClient<T> clientCallback;
|
||||||
|
private LoaderCreator<T> loaderCreator;
|
||||||
|
|
||||||
|
public DataLoaderCallbacks(LoadClient<T> clientCallback, LoaderCreator<T> loaderCreator) {
|
||||||
|
this.clientCallback = clientCallback;
|
||||||
|
this.loaderCreator = loaderCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Loader<DataLoaderResult<T>> onCreateLoader(int id, Bundle args) {
|
||||||
|
try {
|
||||||
|
return loaderCreator.create(id, args);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ExLog.ex(TAG, e);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Exception while creating a loader.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFinished(Loader<DataLoaderResult<T>> loader, DataLoaderResult<T> result) {
|
||||||
|
if (result.isSuccessful()) {
|
||||||
|
clientCallback.onLoadSucceded(result.getResult(), result.isResultCached());
|
||||||
|
} else {
|
||||||
|
clientCallback.onLoadFailed(result.getException());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaderReset(Loader<DataLoaderResult<T>> loader) {
|
||||||
|
// currently we ignore loader resets...
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.data.loaders;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Wrapper class for data loading results.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* A {@link DataLoaderResult} may be successful or failed. It carries either the failure's {@link Exception} or the
|
||||||
|
* actual result.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* result type.
|
||||||
|
*/
|
||||||
|
public class DataLoaderResult<T> {
|
||||||
|
// private static final String TAG = DataLoaderResult.class.getName();
|
||||||
|
|
||||||
|
private final Exception exception;
|
||||||
|
private final boolean cached;
|
||||||
|
private final T result;
|
||||||
|
|
||||||
|
public DataLoaderResult(T result, boolean isCached) {
|
||||||
|
this.result = result;
|
||||||
|
this.cached = isCached;
|
||||||
|
this.exception = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataLoaderResult(Exception exception) {
|
||||||
|
this.exception = exception;
|
||||||
|
this.cached = false;
|
||||||
|
this.result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccessful() {
|
||||||
|
return exception == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exception getException() {
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isResultCached() {
|
||||||
|
if (!isSuccessful()) {
|
||||||
|
throw new IllegalStateException("Failures cannot be cached!");
|
||||||
|
}
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.data.loaders;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Loader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Loader} that (immediately) returns a {@link Callable}'s result. All results are announced as non-cached.
|
||||||
|
*
|
||||||
|
* @param <T> result type.
|
||||||
|
*/
|
||||||
|
public class ImmediateDataLoader<T> extends Loader<DataLoaderResult<T>> {
|
||||||
|
|
||||||
|
private Callable<T> resultCallable;
|
||||||
|
|
||||||
|
public ImmediateDataLoader(Context context, Callable<T> resultCallable) {
|
||||||
|
super(context);
|
||||||
|
this.resultCallable = resultCallable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStartLoading() {
|
||||||
|
publishResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onForceLoad() {
|
||||||
|
publishResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishResult() {
|
||||||
|
try {
|
||||||
|
// We act as a never caching DataLoader to ensure that it looks like remote access!
|
||||||
|
deliverResult(new DataLoaderResult<T>(resultCallable.call(), false));
|
||||||
|
} catch (Exception e) {
|
||||||
|
deliverResult(new DataLoaderResult<T>(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.data.loaders;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Loader;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple wrapper for a {@link DataLoaderCallbacks} creating an {@link ImmediateDataLoader}.
|
||||||
|
* @param <T> the result type.
|
||||||
|
*/
|
||||||
|
public class ImmediateDataLoaderCallbacks<T> extends DataLoaderCallbacks<T> {
|
||||||
|
public ImmediateDataLoaderCallbacks(final Context context, LoadClient<T> clientCallback,
|
||||||
|
final Callable<T> loadingFunc) {
|
||||||
|
super(clientCallback, new LoaderCreator<T>() {
|
||||||
|
@Override
|
||||||
|
public Loader<DataLoaderResult<T>> create(int id, Bundle args) throws Exception {
|
||||||
|
return new ImmediateDataLoader<T>(context, loadingFunc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.data.loaders;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import android.content.AsyncTaskLoader;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Loader;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.data.handlers.DataHandler;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* A {@link Loader} that loads data by accessing a remote resource.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* An {@link OnlineDataLoader} may return cached results as announced by its {@link DataHandler}. Call
|
||||||
|
* {@link OnlineDataLoader#forceLoad()} to ensure that the remote resource is checked for new data.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The data returned by the remote resource is parsed by the given {@link DataParser} and may be cached through your
|
||||||
|
* implementation of {@link DataHandler#onResult(Object)}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* result type.
|
||||||
|
*/
|
||||||
|
public class OnlineDataLoader<T> extends AsyncTaskLoader<DataLoaderResult<T>> {
|
||||||
|
private static final String TAG = OnlineDataLoader.class.getName();
|
||||||
|
|
||||||
|
protected DataParser<T> dataParser;
|
||||||
|
protected DataHandler<T> dataHandler;
|
||||||
|
protected HttpRequest httpRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new {@link OnlineDataLoader} which initiates HTTP GET requests to load the remote data.
|
||||||
|
*/
|
||||||
|
public OnlineDataLoader(Context context, URL requestUrl, DataParser<T> dataParser, DataHandler<T> dataHandler) {
|
||||||
|
this(context, new HttpGetRequest(requestUrl), dataParser, dataHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new {@link OnlineDataLoader} which executes the given {@link HttpRequest} to load the remote data.
|
||||||
|
*/
|
||||||
|
public OnlineDataLoader(Context context, HttpRequest request, DataParser<T> dataParser, DataHandler<T> dataHandler) {
|
||||||
|
super(context);
|
||||||
|
this.httpRequest = request;
|
||||||
|
this.dataParser = dataParser;
|
||||||
|
this.dataHandler = dataHandler;
|
||||||
|
|
||||||
|
ExLog.i(TAG, String.format("Loader created: %s", Integer.toHexString(this.hashCode())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStartLoading() {
|
||||||
|
if (dataHandler.hasCachedResults()) {
|
||||||
|
ExLog.i(TAG, String.format("Using cached results... %s", Integer.toHexString(this.hashCode())));
|
||||||
|
deliverResult(new DataLoaderResult<T>(dataHandler.getCachedResults(), true));
|
||||||
|
} else {
|
||||||
|
ExLog.i(TAG, String.format("No cached results. Forcing load now %s", Integer.toHexString(this.hashCode())));
|
||||||
|
forceLoad();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onForceLoad() {
|
||||||
|
ExLog.i(TAG, String.format("Forcing load %s", Integer.toHexString(this.hashCode())));
|
||||||
|
super.onForceLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deliverResult(DataLoaderResult<T> result) {
|
||||||
|
if (result.isSuccessful()) {
|
||||||
|
dataHandler.onResult(result.getResult());
|
||||||
|
}
|
||||||
|
super.deliverResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataLoaderResult<T> loadInBackground() {
|
||||||
|
try {
|
||||||
|
return new DataLoaderResult<T>(loadDataInBackground(), false);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ExLog.ex(TAG, e);
|
||||||
|
return new DataLoaderResult<T>(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private T loadDataInBackground() throws Exception {
|
||||||
|
Reader reader = null;
|
||||||
|
try {
|
||||||
|
InputStream inputStream = httpRequest.execute();
|
||||||
|
reader = new InputStreamReader(inputStream);
|
||||||
|
return dataParser.parse(reader);
|
||||||
|
} finally {
|
||||||
|
if (reader != null) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-2
@@ -9,11 +9,11 @@ import com.sap.sailing.domain.base.CourseBase;
|
|||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
|
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
|
||||||
|
|
||||||
public class CourseDataParser implements DataParser<CourseBase> {
|
public class CourseBaseParser implements DataParser<CourseBase> {
|
||||||
|
|
||||||
private JsonDeserializer<CourseBase> deserializer;
|
private JsonDeserializer<CourseBase> deserializer;
|
||||||
|
|
||||||
public CourseDataParser(JsonDeserializer<CourseBase> deserializer) {
|
public CourseBaseParser(JsonDeserializer<CourseBase> deserializer) {
|
||||||
this.deserializer = deserializer;
|
this.deserializer = deserializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
+8
-1
@@ -32,7 +32,14 @@ public class FleetIdentifierImpl implements FleetIdentifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Serializable getId() {
|
public Serializable getId() {
|
||||||
return String.format("%s.%s.%s", getRaceGroup().getName(), getSeries().getName(), getFleet().getName());
|
return String.format("%s.%s.%s",
|
||||||
|
escapeIdentifierFragment(getRaceGroup().getName()),
|
||||||
|
escapeIdentifierFragment(getSeries().getName()),
|
||||||
|
escapeIdentifierFragment(getFleet().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String escapeIdentifierFragment(String fragment) {
|
||||||
|
return fragment.replace(".", "\\.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-6
@@ -12,11 +12,7 @@ public class ManagedRaceIdentifierImpl extends FleetIdentifierImpl implements Ma
|
|||||||
|
|
||||||
private String raceName;
|
private String raceName;
|
||||||
|
|
||||||
public ManagedRaceIdentifierImpl(
|
public ManagedRaceIdentifierImpl(String raceName, Fleet fleetWithRaceNames, SeriesBase series, RaceGroup raceGroup) {
|
||||||
String raceName,
|
|
||||||
Fleet fleetWithRaceNames,
|
|
||||||
SeriesBase series,
|
|
||||||
RaceGroup raceGroup) {
|
|
||||||
super(fleetWithRaceNames, series, raceGroup);
|
super(fleetWithRaceNames, series, raceGroup);
|
||||||
this.raceName = raceName;
|
this.raceName = raceName;
|
||||||
}
|
}
|
||||||
@@ -31,7 +27,7 @@ public class ManagedRaceIdentifierImpl extends FleetIdentifierImpl implements Ma
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Serializable getId() {
|
public Serializable getId() {
|
||||||
return String.format("%s.%s", super.getId(), getRaceName());
|
return String.format("%s.%s", super.getId(), escapeIdentifierFragment(getRaceName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+19
@@ -1,5 +1,7 @@
|
|||||||
package com.sap.sailing.racecommittee.app.logging;
|
package com.sap.sailing.racecommittee.app.logging;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
@@ -128,6 +130,10 @@ public class ExLog {
|
|||||||
getInstance().error(tag, msg);
|
getInstance().error(tag, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized static void ex(String tag, Exception e) {
|
||||||
|
getInstance().exception(tag, e);
|
||||||
|
}
|
||||||
|
|
||||||
private final static String logMsgTemplate = "%s - %s - %s : %s";
|
private final static String logMsgTemplate = "%s - %s - %s : %s";
|
||||||
|
|
||||||
private enum LogLevel {
|
private enum LogLevel {
|
||||||
@@ -180,6 +186,19 @@ public class ExLog {
|
|||||||
logToFile(LogLevel.ERROR, tag, msg);
|
logToFile(LogLevel.ERROR, tag, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void exception(String tag, Exception e) {
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
PrintWriter stream = new PrintWriter(stringWriter);
|
||||||
|
e.printStackTrace(stream);
|
||||||
|
String msg = stringWriter.toString();
|
||||||
|
|
||||||
|
if (isTargetActive(Target.LOGCAT))
|
||||||
|
Log.e(tag, msg);
|
||||||
|
|
||||||
|
if (isTargetActive(Target.FILE))
|
||||||
|
logToFile(LogLevel.ERROR, tag, msg);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isTargetActive(Target logcat) {
|
private boolean isTargetActive(Target logcat) {
|
||||||
return activeLoggingTargets.contains(logcat);
|
return activeLoggingTargets.contains(logcat);
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.logging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stolen from API Level 14.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface LifecycleCallbacks {
|
||||||
|
void onCreate(Object activityOrFragment);
|
||||||
|
|
||||||
|
void onStart(Object activityOrFragment);
|
||||||
|
|
||||||
|
void onResume(Object activityOrFragment);
|
||||||
|
|
||||||
|
void onPause(Object activityOrFragment);
|
||||||
|
|
||||||
|
void onStop(Object activityOrFragment);
|
||||||
|
|
||||||
|
void onSaveInstanceState(Object activityOrFragment);
|
||||||
|
|
||||||
|
void onDestroy(Object activityOrFragment);
|
||||||
|
}
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.logging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger to track all activity and fragment lifecycle events.
|
||||||
|
*/
|
||||||
|
public class LifecycleLogger implements LifecycleCallbacks {
|
||||||
|
|
||||||
|
private static final String TAG = LifecycleLogger.class.getName();
|
||||||
|
private static boolean isLifecycleLoggingEnabled = false;
|
||||||
|
|
||||||
|
public static void enableLifecycleLogging(boolean enabled) {
|
||||||
|
isLifecycleLoggingEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onEvent(Object activityOrFragment, String action) {
|
||||||
|
if (isLifecycleLoggingEnabled) {
|
||||||
|
ExLog.i(TAG,
|
||||||
|
String.format("%s %s %s", action, activityOrFragment.getClass().getSimpleName(),
|
||||||
|
Integer.toHexString(System.identityHashCode(activityOrFragment))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Object activityOrFragment) {
|
||||||
|
onEvent(activityOrFragment, "Creating");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart(Object activityOrFragment) {
|
||||||
|
onEvent(activityOrFragment, "Starting");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume(Object activityOrFragment) {
|
||||||
|
onEvent(activityOrFragment, "Resuming");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause(Object activityOrFragment) {
|
||||||
|
onEvent(activityOrFragment, "Pausing");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop(Object activityOrFragment) {
|
||||||
|
onEvent(activityOrFragment, "Stopping");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Object activityOrFragment) {
|
||||||
|
onEvent(activityOrFragment, "Saving instance");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy(Object activityOrFragment) {
|
||||||
|
onEvent(activityOrFragment, "Destroying");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+39
-25
@@ -9,13 +9,15 @@ import java.util.Map.Entry;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.Notification;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
|
||||||
import com.sap.sailing.domain.common.TimePoint;
|
import com.sap.sailing.domain.common.TimePoint;
|
||||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||||
@@ -38,6 +40,7 @@ import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerialize
|
|||||||
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogEventSerializer;
|
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogEventSerializer;
|
||||||
|
|
||||||
public class RaceStateService extends Service {
|
public class RaceStateService extends Service {
|
||||||
|
|
||||||
private final static String TAG = RaceStateService.class.getName();
|
private final static String TAG = RaceStateService.class.getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,6 +53,7 @@ public class RaceStateService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final static String EXTRAS_SERVICE_ID = RaceStateService.class.getName() + ".serviceId";
|
private final static String EXTRAS_SERVICE_ID = RaceStateService.class.getName() + ".serviceId";
|
||||||
|
private final static int NOTIFICATION_ID = 42;
|
||||||
|
|
||||||
private final IBinder mBinder = new RaceStateServiceBinder();
|
private final IBinder mBinder = new RaceStateServiceBinder();
|
||||||
|
|
||||||
@@ -67,6 +71,9 @@ public class RaceStateService extends Service {
|
|||||||
|
|
||||||
private Map<Serializable, List<PendingIntent>> managedIntents;
|
private Map<Serializable, List<PendingIntent>> managedIntents;
|
||||||
|
|
||||||
|
private NotificationManager notificationManager;
|
||||||
|
private NotificationCompat.Builder notificationBuilder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
this.serviceId = UUID.randomUUID();
|
this.serviceId = UUID.randomUUID();
|
||||||
@@ -78,9 +85,26 @@ public class RaceStateService extends Service {
|
|||||||
this.registeredStateEventListeners = new HashMap<ManagedRace, RaceStateEventListener>();
|
this.registeredStateEventListeners = new HashMap<ManagedRace, RaceStateEventListener>();
|
||||||
this.managedIntents = new HashMap<Serializable, List<PendingIntent>>();
|
this.managedIntents = new HashMap<Serializable, List<PendingIntent>>();
|
||||||
|
|
||||||
startForeground();
|
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
ExLog.i(TAG, "Started.");
|
setupNotificationBuilder();
|
||||||
|
|
||||||
|
startForeground(NOTIFICATION_ID, notificationBuilder.build());
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
ExLog.i(TAG, "Started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupNotificationBuilder() {
|
||||||
|
Intent launcherIntent = new Intent(this, LoginActivity.class);
|
||||||
|
launcherIntent.setAction(Intent.ACTION_MAIN);
|
||||||
|
launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
|
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, launcherIntent, 0);
|
||||||
|
notificationBuilder = new NotificationCompat.Builder(this)
|
||||||
|
.setSmallIcon(R.drawable.sap_sailing_app_icon)
|
||||||
|
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.sap_sailing_app_icon))
|
||||||
|
.setContentTitle(getText(R.string.service_info))
|
||||||
|
.setContentText(getText(R.string.service_text_no_races))
|
||||||
|
.setContentIntent(contentIntent)
|
||||||
|
.setOngoing(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,27 +156,6 @@ public class RaceStateService extends Service {
|
|||||||
ExLog.i(TAG, "All races unregistered.");
|
ExLog.i(TAG, "All races unregistered.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startForeground() {
|
|
||||||
CharSequence text = getText(R.string.service_title);
|
|
||||||
|
|
||||||
// Set the icon, scrolling text and timestamp
|
|
||||||
Notification notification = new Notification(R.drawable.sap_sailing_app_icon, text, System.currentTimeMillis());
|
|
||||||
|
|
||||||
Intent intent = new Intent(this, LoginActivity.class);
|
|
||||||
// clear all activities above started and reuse if already existing!
|
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
|
||||||
// The PendingIntent to launch our activity if the user selects this
|
|
||||||
// notification
|
|
||||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
|
|
||||||
|
|
||||||
// Set the info for the views that show in the notification panel.
|
|
||||||
notification.setLatestEventInfo(this, getText(R.string.service_info), text, contentIntent);
|
|
||||||
notification.flags |= Notification.FLAG_NO_CLEAR;
|
|
||||||
|
|
||||||
// Send the notification.
|
|
||||||
this.startForeground(42, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleStartCommand(Intent intent) {
|
private void handleStartCommand(Intent intent) {
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
ExLog.i(TAG, String.format("Command action '%s' received.", action));
|
ExLog.i(TAG, String.format("Command action '%s' received.", action));
|
||||||
@@ -197,6 +200,11 @@ public class RaceStateService extends Service {
|
|||||||
private void handleClearRaces(Intent intent) {
|
private void handleClearRaces(Intent intent) {
|
||||||
unregisterAllRaces();
|
unregisterAllRaces();
|
||||||
clearAllRaces();
|
clearAllRaces();
|
||||||
|
|
||||||
|
notificationManager.notify(NOTIFICATION_ID, notificationBuilder
|
||||||
|
.setNumber(0)
|
||||||
|
.setContentText(getString(R.string.service_text_no_races))
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearAllRaces() {
|
private void clearAllRaces() {
|
||||||
@@ -211,6 +219,12 @@ public class RaceStateService extends Service {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
registerRace(race);
|
registerRace(race);
|
||||||
|
|
||||||
|
int numRaces = managedIntents.keySet().size();
|
||||||
|
notificationManager.notify(NOTIFICATION_ID, notificationBuilder
|
||||||
|
.setNumber(numRaces)
|
||||||
|
.setContentText(String.format(getString(R.string.service_text_num_races), numRaces))
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ManagedRace getRaceFromIntent(Intent intent) {
|
private ManagedRace getRaceFromIntent(Intent intent) {
|
||||||
@@ -245,7 +259,7 @@ public class RaceStateService extends Service {
|
|||||||
|
|
||||||
ExLog.i(TAG, "Race " + race.getId() + " registered.");
|
ExLog.i(TAG, "Race " + race.getId() + " registered.");
|
||||||
} else {
|
} else {
|
||||||
ExLog.e(TAG, "Race " + race.getId() + " was already registered. Ignoring.");
|
ExLog.w(TAG, "Race " + race.getId() + " was already registered. Ignoring.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-9
@@ -1,8 +1,7 @@
|
|||||||
package com.sap.sailing.racecommittee.app.services.sending;
|
package com.sap.sailing.racecommittee.app.services.sending;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URI;
|
import java.net.URL;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
@@ -44,13 +43,8 @@ public class EventSenderTask extends AsyncTask<Intent, Void, Pair<Intent, Intege
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ExLog.i(TAG, "Posting event: " + serializedEvent);
|
ExLog.i(TAG, "Posting event: " + serializedEvent);
|
||||||
HttpRequest post = new HttpJsonPostRequest(URI.create(url), serializedEvent.toString());
|
HttpRequest post = new HttpJsonPostRequest(new URL(url), serializedEvent.toString());
|
||||||
try {
|
post.execute().close();
|
||||||
final InputStream inputStream = post.execute();
|
|
||||||
inputStream.close();
|
|
||||||
} finally {
|
|
||||||
post.disconnect();
|
|
||||||
}
|
|
||||||
ExLog.i(TAG, "Post successful for the following event: " + serializedEvent);
|
ExLog.i(TAG, "Post successful for the following event: " + serializedEvent);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ExLog.e(TAG, String.format("Post not successful, exception occured: %s", e.toString()));
|
ExLog.e(TAG, String.format("Post not successful, exception occured: %s", e.toString()));
|
||||||
|
|||||||
+13
-14
@@ -2,12 +2,10 @@ package com.sap.sailing.racecommittee.app.ui.activities;
|
|||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@@ -25,7 +23,7 @@ import com.sap.sailing.racecommittee.app.services.sending.EventSendingService.Ev
|
|||||||
/**
|
/**
|
||||||
* Base activity for all race committee cockpit activities enabling basic menu functionality.
|
* Base activity for all race committee cockpit activities enabling basic menu functionality.
|
||||||
*/
|
*/
|
||||||
public abstract class BaseActivity extends Activity {
|
public abstract class BaseActivity extends LoggableActivity {
|
||||||
|
|
||||||
private class EventSendingServiceConnection implements ServiceConnection, EventSendingServiceLogger {
|
private class EventSendingServiceConnection implements ServiceConnection, EventSendingServiceLogger {
|
||||||
@Override
|
@Override
|
||||||
@@ -77,7 +75,6 @@ public abstract class BaseActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
// Handle item selection
|
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.options_menu_settings:
|
case R.id.options_menu_settings:
|
||||||
ExLog.i(TAG, "Clicked SETTINGS.");
|
ExLog.i(TAG, "Clicked SETTINGS.");
|
||||||
@@ -86,8 +83,7 @@ public abstract class BaseActivity extends Activity {
|
|||||||
case R.id.options_menu_reload:
|
case R.id.options_menu_reload:
|
||||||
ExLog.i(TAG, "Clicked RESET.");
|
ExLog.i(TAG, "Clicked RESET.");
|
||||||
InMemoryDataStore.INSTANCE.reset();
|
InMemoryDataStore.INSTANCE.reset();
|
||||||
fadeActivity(LoginActivity.class, true);
|
return onReset();
|
||||||
return true;
|
|
||||||
case R.id.options_menu_live:
|
case R.id.options_menu_live:
|
||||||
ExLog.i(TAG, "Clicked LIVE.");
|
ExLog.i(TAG, "Clicked LIVE.");
|
||||||
Toast.makeText(this, getLiveIconText(), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getLiveIconText(), Toast.LENGTH_LONG).show();
|
||||||
@@ -110,30 +106,33 @@ public abstract class BaseActivity extends Activity {
|
|||||||
return super.onPrepareOptionsMenu(menu);
|
return super.onPrepareOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
super.onBackPressed();
|
||||||
|
ExLog.i(TAG, String.format("Back pressed on activity %s", this.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean onHomeClicked() {
|
protected boolean onHomeClicked() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected boolean onReset() {
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
fadeActivity(LoginActivity.class, true);
|
||||||
super.onCreate(savedInstanceState);
|
return true;
|
||||||
ExLog.i(TAG, String.format("Creating activity %s", this.getClass().getSimpleName()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|
||||||
ExLog.i(TAG, String.format("Starting activity %s", this.getClass().getSimpleName()));
|
|
||||||
Intent intent = new Intent(this, EventSendingService.class);
|
Intent intent = new Intent(this, EventSendingService.class);
|
||||||
bindService(intent, sendingServiceConnection, Context.BIND_AUTO_CREATE);
|
bindService(intent, sendingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
|
||||||
ExLog.i(TAG, String.format("Stopping activity %s", this.getClass().getSimpleName()));
|
|
||||||
if (boundSendingService) {
|
if (boundSendingService) {
|
||||||
unbindService(sendingServiceConnection);
|
unbindService(sendingServiceConnection);
|
||||||
boundSendingService = false;
|
boundSendingService = false;
|
||||||
|
|||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.ui.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.LifecycleLogger;
|
||||||
|
|
||||||
|
public abstract class LoggableActivity extends Activity {
|
||||||
|
|
||||||
|
private LifecycleLogger lifeLogger;
|
||||||
|
|
||||||
|
public LoggableActivity() {
|
||||||
|
this.lifeLogger = new LifecycleLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
lifeLogger.onCreate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
lifeLogger.onStart(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
lifeLogger.onResume(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
lifeLogger.onPause(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
lifeLogger.onStop(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
lifeLogger.onDestroy(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-7
@@ -15,7 +15,7 @@ import com.sap.sailing.racecommittee.app.AppConstants;
|
|||||||
import com.sap.sailing.racecommittee.app.AppPreferences;
|
import com.sap.sailing.racecommittee.app.AppPreferences;
|
||||||
import com.sap.sailing.racecommittee.app.R;
|
import com.sap.sailing.racecommittee.app.R;
|
||||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.BaseDialogFragment;
|
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.AttachedDialogFragment;
|
||||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.DialogListenerHost;
|
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.DialogListenerHost;
|
||||||
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.LoginDialog;
|
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.LoginDialog;
|
||||||
import com.sap.sailing.racecommittee.app.ui.fragments.lists.CourseAreaListFragment;
|
import com.sap.sailing.racecommittee.app.ui.fragments.lists.CourseAreaListFragment;
|
||||||
@@ -28,6 +28,8 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
|||||||
CourseAreaSelectedListenerHost, DialogListenerHost {
|
CourseAreaSelectedListenerHost, DialogListenerHost {
|
||||||
private final static String TAG = LoginActivity.class.getName();
|
private final static String TAG = LoginActivity.class.getName();
|
||||||
|
|
||||||
|
private final static String CourseAreaListFragmentTag = "CourseAreaListFragmentTag";
|
||||||
|
|
||||||
private LoginDialog loginDialog;
|
private LoginDialog loginDialog;
|
||||||
private CourseArea selectedCourseArea;
|
private CourseArea selectedCourseArea;
|
||||||
|
|
||||||
@@ -36,6 +38,16 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
|||||||
this.selectedCourseArea = null;
|
this.selectedCourseArea = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onReset() {
|
||||||
|
Fragment courseAreaFragment = getFragmentManager().findFragmentByTag(CourseAreaListFragmentTag);
|
||||||
|
if (courseAreaFragment != null) {
|
||||||
|
getFragmentManager().beginTransaction().remove(courseAreaFragment).commit();
|
||||||
|
}
|
||||||
|
recreate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -49,13 +61,14 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
|||||||
|
|
||||||
// on first create add event list fragment
|
// on first create add event list fragment
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
|
ExLog.i(TAG, "Seems to be first start. Creating event fragment.");
|
||||||
addEventListFragment();
|
addEventListFragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEventListFragment() {
|
private void addEventListFragment() {
|
||||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
transaction.add(R.id.login_view_left_container, new EventListFragment());
|
transaction.replace(R.id.login_view_left_container, new EventListFragment());
|
||||||
transaction.setTransition(FragmentTransaction.TRANSIT_NONE);
|
transaction.setTransition(FragmentTransaction.TRANSIT_NONE);
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
}
|
}
|
||||||
@@ -68,7 +81,7 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
|||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
transaction.setCustomAnimations(R.animator.slide_in, R.animator.slide_out);
|
transaction.setCustomAnimations(R.animator.slide_in, R.animator.slide_out);
|
||||||
transaction.replace(R.id.login_view_right_container, fragment);
|
transaction.replace(R.id.login_view_right_container, fragment, CourseAreaListFragmentTag);
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
ExLog.i("LoginActivity", "CourseFragment created.");
|
ExLog.i("LoginActivity", "CourseFragment created.");
|
||||||
}
|
}
|
||||||
@@ -87,7 +100,6 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showCourseAreaListFragment(Serializable eventId) {
|
private void showCourseAreaListFragment(Serializable eventId) {
|
||||||
Toast.makeText(LoginActivity.this, eventId.toString(), Toast.LENGTH_LONG).show();
|
|
||||||
addCourseAreaListFragment(eventId);
|
addCourseAreaListFragment(eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +126,7 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
|||||||
return new DialogResultListener() {
|
return new DialogResultListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDialogPositiveButton(BaseDialogFragment dialog) {
|
public void onDialogPositiveButton(AttachedDialogFragment dialog) {
|
||||||
switch (loginDialog.getSelectedLoginType()) {
|
switch (loginDialog.getSelectedLoginType()) {
|
||||||
case OFFICER:
|
case OFFICER:
|
||||||
ExLog.i(TAG, "Communication with backend is active.");
|
ExLog.i(TAG, "Communication with backend is active.");
|
||||||
@@ -136,14 +148,13 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Toast.makeText(LoginActivity.this, selectedCourseArea.getId().toString(), Toast.LENGTH_LONG).show();
|
|
||||||
Intent message = new Intent(LoginActivity.this, RacingActivity.class);
|
Intent message = new Intent(LoginActivity.this, RacingActivity.class);
|
||||||
message.putExtra(AppConstants.COURSE_AREA_UUID_KEY, selectedCourseArea.getId());
|
message.putExtra(AppConstants.COURSE_AREA_UUID_KEY, selectedCourseArea.getId());
|
||||||
fadeActivity(message);
|
fadeActivity(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDialogNegativeButton(BaseDialogFragment dialog) {
|
public void onDialogNegativeButton(AttachedDialogFragment dialog) {
|
||||||
/* nothing here... */
|
/* nothing here... */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+64
-61
@@ -31,13 +31,16 @@ import com.sap.sailing.racecommittee.app.ui.fragments.RaceInfoFragment;
|
|||||||
import com.sap.sailing.racecommittee.app.ui.fragments.lists.ManagedRaceListFragment;
|
import com.sap.sailing.racecommittee.app.ui.fragments.lists.ManagedRaceListFragment;
|
||||||
import com.sap.sailing.racecommittee.app.ui.fragments.lists.ManagedRaceListFragment.FilterMode;
|
import com.sap.sailing.racecommittee.app.ui.fragments.lists.ManagedRaceListFragment.FilterMode;
|
||||||
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceInfoListener;
|
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceInfoListener;
|
||||||
|
import com.sap.sailing.racecommittee.app.utils.CollectionUtils;
|
||||||
|
|
||||||
public class RacingActivity extends BaseActivity implements RaceInfoListener {
|
public class RacingActivity extends SessionActivity implements RaceInfoListener {
|
||||||
// private final static String TAG = RacingActivity.class.getName();
|
// private final static String TAG = RacingActivity.class.getName();
|
||||||
private final static String ListFragmentTag = RacingActivity.class.getName() + ".ManagedRaceListFragment";
|
private final static String ListFragmentTag = RacingActivity.class.getName() + ".ManagedRaceListFragment";
|
||||||
|
|
||||||
private static final String TAG = RacingActivity.class.getName();
|
private static final String TAG = RacingActivity.class.getName();
|
||||||
|
|
||||||
|
private static final int RacesLoaderId = 0;
|
||||||
|
|
||||||
private class FilterModeSelectionBinder implements OnNavigationListener {
|
private class FilterModeSelectionBinder implements OnNavigationListener {
|
||||||
|
|
||||||
private ManagedRaceListFragment targetList;
|
private ManagedRaceListFragment targetList;
|
||||||
@@ -68,6 +71,59 @@ public class RacingActivity extends BaseActivity implements RaceInfoListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RaceLoadClient implements LoadClient<Collection<ManagedRace>> {
|
||||||
|
|
||||||
|
private Collection<ManagedRace> lastSeenRaces = null;
|
||||||
|
private CourseArea courseArea;
|
||||||
|
|
||||||
|
public RaceLoadClient(CourseArea courseArea) {
|
||||||
|
this.courseArea = courseArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadSucceded(Collection<ManagedRace> data, boolean isCached) {
|
||||||
|
setProgressBarIndeterminateVisibility(false);
|
||||||
|
|
||||||
|
// Let's do the setup stuff only when the data is changed (or its the first time)
|
||||||
|
if (lastSeenRaces != null && CollectionUtils.isEqualCollection(data, lastSeenRaces)) {
|
||||||
|
ExLog.i(TAG, "Same races are already loaded...");
|
||||||
|
} else {
|
||||||
|
lastSeenRaces = data;
|
||||||
|
|
||||||
|
registerOnService(data);
|
||||||
|
raceListFragment.setupOn(data);
|
||||||
|
|
||||||
|
Toast.makeText(RacingActivity.this,
|
||||||
|
String.format(getString(R.string.racing_load_success), data.size()), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFailed(Exception reason) {
|
||||||
|
setProgressBarIndeterminateVisibility(false);
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(RacingActivity.this);
|
||||||
|
builder.setMessage(String.format(getString(R.string.generic_load_failure), reason.getMessage()))
|
||||||
|
.setTitle(getString(R.string.loading_failure)).setIcon(R.drawable.ic_dialog_alert_holo_light)
|
||||||
|
.setCancelable(true)
|
||||||
|
.setPositiveButton(getString(R.string.retry), new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
setProgressBarIndeterminateVisibility(true);
|
||||||
|
|
||||||
|
ExLog.i(TAG, "Issuing a reload of managed races");
|
||||||
|
getLoaderManager().restartLoader(RacesLoaderId, null,
|
||||||
|
dataManager.createRacesLoader(courseArea.getId(), RaceLoadClient.this));
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
}).setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.create().show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selection list of all races
|
* Selection list of all races
|
||||||
*/
|
*/
|
||||||
@@ -80,12 +136,6 @@ public class RacingActivity extends BaseActivity implements RaceInfoListener {
|
|||||||
|
|
||||||
private ReadonlyDataManager dataManager;
|
private ReadonlyDataManager dataManager;
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean onHomeClicked() {
|
|
||||||
fadeActivity(LoginActivity.class, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
// features must be requested before anything else
|
// features must be requested before anything else
|
||||||
@@ -109,12 +159,15 @@ public class RacingActivity extends BaseActivity implements RaceInfoListener {
|
|||||||
Toast.makeText(this, getString(R.string.racing_course_area_missing), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.racing_course_area_missing), Toast.LENGTH_LONG).show();
|
||||||
} else {
|
} else {
|
||||||
setupActionBar(courseArea);
|
setupActionBar(courseArea);
|
||||||
// unload and unregister from all races here!
|
|
||||||
unloadAllRaces();
|
|
||||||
loadRaces(courseArea);
|
loadRaces(courseArea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
logoutSession();
|
||||||
|
}
|
||||||
|
|
||||||
private ManagedRaceListFragment getOrCreateRaceListFragment() {
|
private ManagedRaceListFragment getOrCreateRaceListFragment() {
|
||||||
Fragment fragment = getFragmentManager().findFragmentByTag(ListFragmentTag);
|
Fragment fragment = getFragmentManager().findFragmentByTag(ListFragmentTag);
|
||||||
// on first create add race list fragment
|
// on first create add race list fragment
|
||||||
@@ -149,8 +202,6 @@ public class RacingActivity extends BaseActivity implements RaceInfoListener {
|
|||||||
|
|
||||||
private void setupActionBar(CourseArea courseArea) {
|
private void setupActionBar(CourseArea courseArea) {
|
||||||
ActionBar actionBar = getActionBar();
|
ActionBar actionBar = getActionBar();
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
|
|
||||||
actionBar.setTitle(String.format(getString(R.string.racingview_header), courseArea.getName()));
|
actionBar.setTitle(String.format(getString(R.string.racingview_header), courseArea.getName()));
|
||||||
|
|
||||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
|
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
|
||||||
@@ -160,40 +211,12 @@ public class RacingActivity extends BaseActivity implements RaceInfoListener {
|
|||||||
new FilterModeSelectionBinder(raceListFragment, actionBar, adapter, ManagedRaceListFragment.FilterMode.values());
|
new FilterModeSelectionBinder(raceListFragment, actionBar, adapter, ManagedRaceListFragment.FilterMode.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unloadAllRaces() {
|
|
||||||
ExLog.i(TAG, "Issuing intent action clear races");
|
|
||||||
Intent intent = new Intent(AppConstants.INTENT_ACTION_CLEAR_RACES);
|
|
||||||
this.startService(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadRaces(final CourseArea courseArea) {
|
private void loadRaces(final CourseArea courseArea) {
|
||||||
setProgressBarIndeterminateVisibility(true);
|
setProgressBarIndeterminateVisibility(true);
|
||||||
|
|
||||||
ExLog.i(TAG, "Issuing loading of managed races from data manager");
|
ExLog.i(TAG, "Issuing loading of managed races from data manager");
|
||||||
dataManager.loadRaces(courseArea.getId(), new LoadClient<Collection<ManagedRace>>() {
|
getLoaderManager().initLoader(RacesLoaderId, null,
|
||||||
public void onLoadSucceded(Collection<ManagedRace> data) {
|
dataManager.createRacesLoader(courseArea.getId(), new RaceLoadClient(courseArea)));
|
||||||
onLoadRacesSucceded(courseArea, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onLoadFailed(Exception reason) {
|
|
||||||
onLoadRacesFailed(courseArea, reason);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onLoadRacesSucceded(CourseArea courseArea, Collection<ManagedRace> data) {
|
|
||||||
setProgressBarIndeterminateVisibility(false);
|
|
||||||
|
|
||||||
registerOnService(data);
|
|
||||||
raceListFragment.setupOn(data);
|
|
||||||
|
|
||||||
Toast.makeText(RacingActivity.this, String.format(getString(R.string.racing_load_success), data.size()),
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onLoadRacesFailed(final CourseArea courseArea, Exception reason) {
|
|
||||||
setProgressBarIndeterminateVisibility(false);
|
|
||||||
showLoadFailedDialog(courseArea, reason.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerOnService(Collection<ManagedRace> races) {
|
private void registerOnService(Collection<ManagedRace> races) {
|
||||||
@@ -207,26 +230,6 @@ public class RacingActivity extends BaseActivity implements RaceInfoListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showLoadFailedDialog(final CourseArea courseArea, String message) {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setMessage(
|
|
||||||
String.format(getString(R.string.generic_load_failure), message))
|
|
||||||
.setTitle(getString(R.string.loading_failure)).setIcon(R.drawable.ic_dialog_alert_holo_light).setCancelable(true)
|
|
||||||
.setPositiveButton(getString(R.string.retry), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
loadRaces(courseArea);
|
|
||||||
}
|
|
||||||
}).setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
dialog.cancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!isFinishing()) {
|
|
||||||
AlertDialog alert = builder.create();
|
|
||||||
alert.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onRaceItemClicked(ManagedRace managedRace) {
|
public void onRaceItemClicked(ManagedRace managedRace) {
|
||||||
infoFragment = new RaceInfoFragment();
|
infoFragment = new RaceInfoFragment();
|
||||||
infoFragment.setArguments(RaceFragment.createArguments(managedRace));
|
infoFragment.setArguments(RaceFragment.createArguments(managedRace));
|
||||||
|
|||||||
+4
-11
@@ -29,7 +29,7 @@ import com.sap.sailing.racecommittee.app.ui.adapters.PhotoAdapter;
|
|||||||
import com.sap.sailing.racecommittee.app.ui.views.CameraView;
|
import com.sap.sailing.racecommittee.app.ui.views.CameraView;
|
||||||
import com.sap.sailing.racecommittee.app.utils.MailHelper;
|
import com.sap.sailing.racecommittee.app.utils.MailHelper;
|
||||||
|
|
||||||
public class ResultsCapturingActivity extends BaseActivity {
|
public class ResultsCapturingActivity extends SessionActivity {
|
||||||
private static String ARGUMENTS_KEY_SUBJECT = "subject";
|
private static String ARGUMENTS_KEY_SUBJECT = "subject";
|
||||||
private static String ARGUMENTS_KEY_TEXT = "text";
|
private static String ARGUMENTS_KEY_TEXT = "text";
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public class ResultsCapturingActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setupActionBar();
|
setupActionBar();
|
||||||
|
|
||||||
@@ -111,13 +111,13 @@ public class ResultsCapturingActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
setupCamera();
|
setupCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
releaseCamera();
|
releaseCamera();
|
||||||
}
|
}
|
||||||
@@ -161,12 +161,6 @@ public class ResultsCapturingActivity extends BaseActivity {
|
|||||||
currentImageFile = createFinisherImageFile(currentImageIndex++);
|
currentImageFile = createFinisherImageFile(currentImageIndex++);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean onHomeClicked() {
|
|
||||||
fadeActivity(LoginActivity.class, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupListView() {
|
private void setupListView() {
|
||||||
TextView header = new TextView(this);
|
TextView header = new TextView(this);
|
||||||
header.setText(getString(R.string.results_capturing_view_list_header));
|
header.setText(getString(R.string.results_capturing_view_list_header));
|
||||||
@@ -181,7 +175,6 @@ public class ResultsCapturingActivity extends BaseActivity {
|
|||||||
|
|
||||||
private void setupActionBar() {
|
private void setupActionBar() {
|
||||||
ActionBar actionBar = getActionBar();
|
ActionBar actionBar = getActionBar();
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
actionBar.setTitle(getString(R.string.results_capturing_title));
|
actionBar.setTitle(getString(R.string.results_capturing_title));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.ui.activities;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||||
|
import com.sap.sailing.racecommittee.app.R;
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
|
|
||||||
|
import android.app.ActionBar;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.DialogInterface.OnClickListener;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class SessionActivity extends BaseActivity {
|
||||||
|
|
||||||
|
private static final String TAG = BaseActivity.class.getName();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
ActionBar actionBar = getActionBar();
|
||||||
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
ExLog.i(TAG, String.format("Logging in from activity %s", this.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onHomeClicked() {
|
||||||
|
return logoutSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onReset() {
|
||||||
|
return logoutSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean logoutSession() {
|
||||||
|
ExLog.i(TAG, String.format("Logging out from activity %s", this.getClass().getSimpleName()));
|
||||||
|
AlertDialog dialog = new AlertDialog.Builder(this)
|
||||||
|
.setTitle(getString(R.string.logout_dialog_title))
|
||||||
|
.setMessage(getString(R.string.logout_dialog_message))
|
||||||
|
.setPositiveButton(getString(R.string.logout), new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
doLogout();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(getString(R.string.cancel), new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
/* nothing here */
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
dialog.show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doLogout() {
|
||||||
|
unloadAllRaces();
|
||||||
|
fadeActivity(LoginActivity.class, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unloadAllRaces() {
|
||||||
|
ExLog.i(TAG, "Issuing intent action clear races");
|
||||||
|
Intent intent = new Intent(AppConstants.INTENT_ACTION_CLEAR_RACES);
|
||||||
|
this.startService(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+18
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.racecommittee.app.ui.activities;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
@@ -24,6 +25,11 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
addPreferencesFromResource(R.layout.settings_view);
|
addPreferencesFromResource(R.layout.settings_view);
|
||||||
|
|
||||||
|
setupStartProcedurePreferences();
|
||||||
|
setupLanguageButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupStartProcedurePreferences() {
|
||||||
final ListPreference startProcedurePreference = (ListPreference) findPreference("defaultStartProcedureType");
|
final ListPreference startProcedurePreference = (ListPreference) findPreference("defaultStartProcedureType");
|
||||||
|
|
||||||
List<CharSequence> entries = new ArrayList<CharSequence>();
|
List<CharSequence> entries = new ArrayList<CharSequence>();
|
||||||
@@ -47,8 +53,19 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupLanguageButton() {
|
||||||
|
Preference button = (Preference)findPreference("languagePref");
|
||||||
|
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference arg0) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
intent.setClassName("com.android.settings", "com.android.settings.LanguageSettings");
|
||||||
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -15,7 +15,7 @@ import com.sap.sailing.racecommittee.app.R;
|
|||||||
public class SystemInformationActivity extends BaseActivity {
|
public class SystemInformationActivity extends BaseActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.system_information_view);
|
setContentView(R.layout.system_information_view);
|
||||||
setupVersionView();
|
setupVersionView();
|
||||||
|
|||||||
+18
-18
@@ -20,6 +20,7 @@ import android.widget.Button;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.sap.sailing.domain.common.Bearing;
|
import com.sap.sailing.domain.common.Bearing;
|
||||||
@@ -37,9 +38,8 @@ import com.sap.sailing.racecommittee.app.R;
|
|||||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
import com.sap.sailing.racecommittee.app.ui.views.CompassView;
|
import com.sap.sailing.racecommittee.app.ui.views.CompassView;
|
||||||
import com.sap.sailing.racecommittee.app.ui.views.CompassView.CompassDirectionListener;
|
import com.sap.sailing.racecommittee.app.ui.views.CompassView.CompassDirectionListener;
|
||||||
import com.sap.sailing.racecommittee.app.utils.GeoUtils;
|
|
||||||
|
|
||||||
public class WindActivity extends BaseActivity implements CompassDirectionListener, LocationListener {
|
public class WindActivity extends SessionActivity implements CompassDirectionListener, LocationListener {
|
||||||
|
|
||||||
private final static int FIVE_SEC = 5000;
|
private final static int FIVE_SEC = 5000;
|
||||||
private final static int EVERY_POSITION_CHANGE = 0;
|
private final static int EVERY_POSITION_CHANGE = 0;
|
||||||
@@ -47,10 +47,9 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
|||||||
CompassView compassView;
|
CompassView compassView;
|
||||||
EditText windBearingEditText;
|
EditText windBearingEditText;
|
||||||
EditText windSpeedEditText;
|
EditText windSpeedEditText;
|
||||||
EditText latitudeEditText;
|
|
||||||
EditText longitudeEditText;
|
|
||||||
SeekBar windSpeedSeekBar;
|
SeekBar windSpeedSeekBar;
|
||||||
Button sendButton;
|
Button sendButton;
|
||||||
|
TextView waitingForGpsTextView;
|
||||||
|
|
||||||
LocationManager locationManager;
|
LocationManager locationManager;
|
||||||
Location currentLocation;
|
Location currentLocation;
|
||||||
@@ -58,17 +57,16 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
|||||||
DecimalFormat bearingFormat;
|
DecimalFormat bearingFormat;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.wind_view);
|
setContentView(R.layout.wind_view);
|
||||||
|
|
||||||
compassView = (CompassView) findViewById(R.id.compassView);
|
compassView = (CompassView) findViewById(R.id.compassView);
|
||||||
windBearingEditText = (EditText) findViewById(R.id.editTextWindDirection);
|
windBearingEditText = (EditText) findViewById(R.id.editTextWindDirection);
|
||||||
windSpeedEditText = (EditText) findViewById(R.id.editTextWindSpeed);
|
windSpeedEditText = (EditText) findViewById(R.id.editTextWindSpeed);
|
||||||
latitudeEditText = (EditText) findViewById(R.id.et_position_lat);
|
|
||||||
longitudeEditText = (EditText) findViewById(R.id.et_position_lon);
|
|
||||||
windSpeedSeekBar = (SeekBar) findViewById(R.id.seekbar_wind_speed);
|
windSpeedSeekBar = (SeekBar) findViewById(R.id.seekbar_wind_speed);
|
||||||
sendButton = (Button) findViewById(R.id.btn_wind_send);
|
sendButton = (Button) findViewById(R.id.btn_wind_send);
|
||||||
|
waitingForGpsTextView = (TextView) findViewById(R.id.textWaitingForGPS);
|
||||||
|
|
||||||
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||||
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
|
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
|
||||||
@@ -144,9 +142,9 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
|||||||
double enteredWindSpeed = AppPreferences.getWindSpeed(this);
|
double enteredWindSpeed = AppPreferences.getWindSpeed(this);
|
||||||
windSpeedSeekBar.setProgress(Double.valueOf(enteredWindSpeed).intValue() * 10);
|
windSpeedSeekBar.setProgress(Double.valueOf(enteredWindSpeed).intValue() * 10);
|
||||||
windSpeedEditText.setText(speedFormat.format(enteredWindSpeed));
|
windSpeedEditText.setText(speedFormat.format(enteredWindSpeed));
|
||||||
double enteredWindBearing = AppPreferences.getWindBearing(this);
|
double enteredWindBearingFrom = AppPreferences.getWindBearingFromDirection(this);
|
||||||
compassView.setDirection((float)enteredWindBearing);
|
compassView.setDirection((float)enteredWindBearingFrom);
|
||||||
windBearingEditText.setText(bearingFormat.format(enteredWindBearing));
|
windBearingEditText.setText(bearingFormat.format(enteredWindBearingFrom));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildAlertMessageNoGps() {
|
private void buildAlertMessageNoGps() {
|
||||||
@@ -169,12 +167,14 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
|||||||
|
|
||||||
|
|
||||||
protected void saveEntriesInPreferences(Wind wind) {
|
protected void saveEntriesInPreferences(Wind wind) {
|
||||||
AppPreferences.setWindBearing(getBaseContext(), wind.getBearing().getDegrees());
|
// Wind.getBearing() returns a value that assumes that the wind flows in that direction
|
||||||
|
// But for this app we need to display the direction the wind is coming from
|
||||||
|
AppPreferences.setWindBearingFromDirection(getBaseContext(), wind.getBearing().reverse().getDegrees());
|
||||||
AppPreferences.setWindSpeed(getBaseContext(), wind.getKnots());
|
AppPreferences.setWindSpeed(getBaseContext(), wind.getKnots());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|
||||||
compassView.setDirectionListener(this);
|
compassView.setDirectionListener(this);
|
||||||
@@ -187,7 +187,7 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
public void onPause() {
|
||||||
locationManager.removeUpdates(this);
|
locationManager.removeUpdates(this);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
@@ -195,8 +195,7 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
|||||||
@Override
|
@Override
|
||||||
public void onLocationChanged(Location location) {
|
public void onLocationChanged(Location location) {
|
||||||
currentLocation = location;
|
currentLocation = location;
|
||||||
latitudeEditText.setText(String.valueOf(GeoUtils.getDegMinSecFormatForDecimalDegree(location.getLatitude())));
|
waitingForGpsTextView.setText("");
|
||||||
longitudeEditText.setText(String.valueOf(GeoUtils.getDegMinSecFormatForDecimalDegree(location.getLongitude())));
|
|
||||||
sendButton.setEnabled(true);
|
sendButton.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,9 +226,10 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
|||||||
Position currentPosition = new DegreePosition(currentLocation.getLatitude(), currentLocation.getLongitude());
|
Position currentPosition = new DegreePosition(currentLocation.getLatitude(), currentLocation.getLongitude());
|
||||||
double windSpeed = Double.valueOf(windSpeedEditText.getText().toString().replace(",", "."));
|
double windSpeed = Double.valueOf(windSpeedEditText.getText().toString().replace(",", "."));
|
||||||
double windBearing = Double.valueOf(windBearingEditText.getText().toString());
|
double windBearing = Double.valueOf(windBearingEditText.getText().toString());
|
||||||
Bearing bearing = new DegreeBearingImpl(windBearing);
|
Bearing bearing_from = new DegreeBearingImpl(windBearing);
|
||||||
SpeedWithBearing speedBearing = new KnotSpeedWithBearingImpl(windSpeed, bearing);
|
// this is not a standard bearing but the direction where the wind comes from, needs to be converted
|
||||||
|
// to match the assumption that a bearing is always the direction the wind flows to
|
||||||
|
SpeedWithBearing speedBearing = new KnotSpeedWithBearingImpl(windSpeed, bearing_from.reverse());
|
||||||
return new WindImpl(currentPosition, MillisecondsTimePoint.now(), speedBearing);
|
return new WindImpl(currentPosition, MillisecondsTimePoint.now(), speedBearing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.ui.fragments;
|
||||||
|
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.LifecycleLogger;
|
||||||
|
|
||||||
|
public abstract class LoggableFragment extends Fragment {
|
||||||
|
|
||||||
|
private LifecycleLogger lifeLogger;
|
||||||
|
|
||||||
|
public LoggableFragment() {
|
||||||
|
this.lifeLogger = new LifecycleLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
lifeLogger.onCreate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
lifeLogger.onStart(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
lifeLogger.onResume(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
lifeLogger.onPause(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
lifeLogger.onStop(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
lifeLogger.onDestroy(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
-4
@@ -2,16 +2,17 @@ package com.sap.sailing.racecommittee.app.ui.fragments;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.sap.sailing.racecommittee.app.AppConstants;
|
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
||||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
import com.sap.sailing.racecommittee.app.utils.TickListener;
|
import com.sap.sailing.racecommittee.app.utils.TickListener;
|
||||||
import com.sap.sailing.racecommittee.app.utils.TickSingleton;
|
import com.sap.sailing.racecommittee.app.utils.TickSingleton;
|
||||||
|
|
||||||
import android.app.Fragment;
|
public abstract class RaceFragment extends LoggableFragment implements TickListener {
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
public abstract class RaceFragment extends Fragment implements TickListener {
|
//private static final String TAG = RaceFragment.class.getName();
|
||||||
|
|
||||||
public static Bundle createArguments(ManagedRace race) {
|
public static Bundle createArguments(ManagedRace race) {
|
||||||
Bundle arguments = new Bundle();
|
Bundle arguments = new Bundle();
|
||||||
@@ -63,7 +64,7 @@ public abstract class RaceFragment extends Fragment implements TickListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyTick() {
|
public void notifyTick() {
|
||||||
// may be overriden in subclasses.
|
// see subclasses.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -218,7 +218,7 @@ public class RaceInfoFragment extends RaceFragment implements RaceStateChangedLi
|
|||||||
LastWindFixFinder windFinder = new LastWindFixFinder(getRace().getState().getRaceLog());
|
LastWindFixFinder windFinder = new LastWindFixFinder(getRace().getState().getRaceLog());
|
||||||
if (windFinder.analyze()!=null){
|
if (windFinder.analyze()!=null){
|
||||||
Wind wind = windFinder.analyze();
|
Wind wind = windFinder.analyze();
|
||||||
windInfoHeader.setText(String.format(getString(R.string.wind_info), wind.getKnots(), wind.getBearing().toString()));
|
windInfoHeader.setText(String.format(getString(R.string.wind_info), wind.getKnots(), wind.getBearing().reverse().toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -29,9 +29,9 @@ public class RaceInfoFragmentChooser {
|
|||||||
|
|
||||||
private RaceFragment createInfoFragment(Class<? extends RaceFragment> fragmentClass, ManagedRace managedRace) {
|
private RaceFragment createInfoFragment(Class<? extends RaceFragment> fragmentClass, ManagedRace managedRace) {
|
||||||
try {
|
try {
|
||||||
|
ExLog.i(TAG, String.format("Fragment %s is chosen.", fragmentClass.getName()));
|
||||||
RaceFragment fragment = fragmentClass.newInstance();
|
RaceFragment fragment = fragmentClass.newInstance();
|
||||||
fragment.setArguments(RaceFragment.createArguments(managedRace));
|
fragment.setArguments(RaceFragment.createArguments(managedRace));
|
||||||
ExLog.i(TAG, String.format("Fragment %s may be choosen", fragmentClass.getName()));
|
|
||||||
return fragment;
|
return fragment;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ExLog.e(TAG, String.format("Exception while instantiating race info fragment:\n%s", e.toString()));
|
ExLog.e(TAG, String.format("Exception while instantiating race info fragment:\n%s", e.toString()));
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
||||||
|
|
||||||
|
|
||||||
public abstract class ActivityAttachedDialogFragment extends BaseDialogFragment {
|
public abstract class ActivityAttachedDialogFragment extends AttachedDialogFragment {
|
||||||
|
|
||||||
protected DialogListenerHost hostActivity;
|
protected DialogListenerHost hostActivity;
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -1,17 +1,16 @@
|
|||||||
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
||||||
|
|
||||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.AlertDialog.Builder;
|
import android.app.AlertDialog.Builder;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
public abstract class BaseDialogFragment extends DialogFragment {
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
private final static String TAG = BaseDialogFragment.class.getName();
|
|
||||||
|
public abstract class AttachedDialogFragment extends LoggableDialogFragment {
|
||||||
|
private final static String TAG = AttachedDialogFragment.class.getName();
|
||||||
|
|
||||||
protected abstract CharSequence getNegativeButtonLabel();
|
protected abstract CharSequence getNegativeButtonLabel();
|
||||||
|
|
||||||
+3
-4
@@ -1,15 +1,14 @@
|
|||||||
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
||||||
|
|
||||||
import com.sap.sailing.racecommittee.app.R;
|
|
||||||
|
|
||||||
import android.app.DatePickerDialog;
|
import android.app.DatePickerDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.widget.DatePicker;
|
import android.widget.DatePicker;
|
||||||
|
|
||||||
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener,
|
import com.sap.sailing.racecommittee.app.R;
|
||||||
|
|
||||||
|
public class DatePickerFragment extends LoggableDialogFragment implements DatePickerDialog.OnDateSetListener,
|
||||||
DatePickerDialog.OnDismissListener {
|
DatePickerDialog.OnDismissListener {
|
||||||
|
|
||||||
private DatePickerDialog.OnDateSetListener listener;
|
private DatePickerDialog.OnDateSetListener listener;
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@ package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
|||||||
|
|
||||||
public interface DialogListenerHost {
|
public interface DialogListenerHost {
|
||||||
public interface DialogResultListener {
|
public interface DialogResultListener {
|
||||||
void onDialogNegativeButton(BaseDialogFragment dialog);
|
void onDialogNegativeButton(AttachedDialogFragment dialog);
|
||||||
void onDialogPositiveButton(BaseDialogFragment dialog);
|
void onDialogPositiveButton(AttachedDialogFragment dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogResultListener getListener();
|
DialogResultListener getListener();
|
||||||
|
|||||||
+48
-63
@@ -7,6 +7,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Loader;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -47,7 +48,9 @@ import com.sap.sailing.racecommittee.app.ui.comparators.NaturalNamedComparator;
|
|||||||
import com.sap.sailing.racecommittee.app.utils.ESSMarkImageHelper;
|
import com.sap.sailing.racecommittee.app.utils.ESSMarkImageHelper;
|
||||||
|
|
||||||
public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
||||||
//private final static String TAG = ESSCourseDesignDialogFragment.class.getName();
|
// private final static String TAG = ESSCourseDesignDialogFragment.class.getName();
|
||||||
|
|
||||||
|
private static int MarksLoaderId = 0;
|
||||||
|
|
||||||
private List<Mark> aMarkList;
|
private List<Mark> aMarkList;
|
||||||
private MarkGridAdapter gridAdapter;
|
private MarkGridAdapter gridAdapter;
|
||||||
@@ -89,11 +92,13 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
previousCourseElements = new ArrayList<CourseListDataElement>();
|
previousCourseElements = new ArrayList<CourseListDataElement>();
|
||||||
|
|
||||||
gridAdapter = new MarkGridAdapter(getActivity(), aMarkList, ESSMarkImageHelper.getInstance());
|
gridAdapter = new MarkGridAdapter(getActivity(), aMarkList, ESSMarkImageHelper.getInstance());
|
||||||
courseElementAdapter = new DraggableCourseElementListAdapter(getActivity(), courseElements, ESSMarkImageHelper.getInstance());
|
courseElementAdapter = new DraggableCourseElementListAdapter(getActivity(), courseElements,
|
||||||
previousCourseElementAdapter = new CourseElementListAdapter(getActivity(), previousCourseElements, ESSMarkImageHelper.getInstance());
|
ESSMarkImageHelper.getInstance());
|
||||||
|
previousCourseElementAdapter = new CourseElementListAdapter(getActivity(), previousCourseElements,
|
||||||
|
ESSMarkImageHelper.getInstance());
|
||||||
|
|
||||||
loadMarks();
|
loadMarks();
|
||||||
loadCourseOnServer();
|
fillPreviousCourseElementsWithLastPublishedCourseDesign();
|
||||||
|
|
||||||
GridView gridView = (GridView) getView().findViewById(R.id.gridViewAssets);
|
GridView gridView = (GridView) getView().findViewById(R.id.gridViewAssets);
|
||||||
gridView.setAdapter(gridAdapter);
|
gridView.setAdapter(gridAdapter);
|
||||||
@@ -163,14 +168,12 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
} else {
|
} else {
|
||||||
copyPreviousToNewCourseDesign();
|
copyPreviousToNewCourseDesign();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Toast.makeText(getActivity(), "No course available to copy", Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), "No course available to copy", Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
publishButton = (Button) getView().findViewById(R.id.publishCourseDesignButton);
|
publishButton = (Button) getView().findViewById(R.id.publishCourseDesignButton);
|
||||||
publishButton.setOnClickListener(new OnClickListener() {
|
publishButton.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
@@ -180,13 +183,19 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
sendCourseDataAndDismiss(courseData);
|
sendCourseDataAndDismiss(courseData);
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
if (ex.getMessage().equals("Gate has no right buoy")) {
|
if (ex.getMessage().equals("Gate has no right buoy")) {
|
||||||
Toast.makeText(getActivity(), "A right buoy is missing for a gate. Please select the right buoy.", Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(),
|
||||||
|
"A right buoy is missing for a gate. Please select the right buoy.", Toast.LENGTH_LONG)
|
||||||
|
.show();
|
||||||
} else if (ex.getMessage().equals("Each waypoints needs a passing side")) {
|
} else if (ex.getMessage().equals("Each waypoints needs a passing side")) {
|
||||||
Toast.makeText(getActivity(), "A waypoint has no passing side. Please select the passing side by clicking long on the waypoint.", Toast.LENGTH_LONG).show();
|
Toast.makeText(
|
||||||
|
getActivity(),
|
||||||
|
"A waypoint has no passing side. Please select the passing side by clicking long on the waypoint.",
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
Toast.makeText(getActivity(), "The course design has to have at least one waypoint.", Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), "The course design has to have at least one waypoint.",
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,19 +203,16 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
|
|
||||||
unpublishButton = (Button) getView().findViewById(R.id.unpublishCourseDesignButton);
|
unpublishButton = (Button) getView().findViewById(R.id.unpublishCourseDesignButton);
|
||||||
unpublishButton.setOnClickListener(new OnClickListener() {
|
unpublishButton.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View arg0) {
|
public void onClick(View arg0) {
|
||||||
CourseBase emptyCourse = new CourseDataImpl("Unpublished course design");
|
CourseBase emptyCourse = new CourseDataImpl("Unpublished course design");
|
||||||
sendCourseDataAndDismiss(emptyCourse);
|
sendCourseDataAndDismiss(emptyCourse);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a DragSortController and thereby defines the behaviour of the drag sort list
|
* Creates a DragSortController and thereby defines the behavior of the drag sort list
|
||||||
*/
|
*/
|
||||||
public DragSortController buildDragSortController(DragSortListView dragSortListView) {
|
public DragSortController buildDragSortController(DragSortListView dragSortListView) {
|
||||||
DragSortController controller = new DragSortController(dragSortListView);
|
DragSortController controller = new DragSortController(dragSortListView);
|
||||||
@@ -220,53 +226,29 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
onLoadMarksSucceeded(dataManager.getDataStore().getMarks());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadCourseOnServer() {
|
|
||||||
dataManager.loadCourse(getRace(), new LoadClient<CourseBase>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadFailed(Exception reason) {
|
|
||||||
fillPreviousCourseElementsWithLastPublishedCourseDesign();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadSucceded(CourseBase data) {
|
|
||||||
/*if (Util.size(data.getWaypoints()) > 0) {
|
|
||||||
fillPreviousCourseElementsInList(data);
|
|
||||||
} else*/ {
|
|
||||||
fillPreviousCourseElementsWithLastPublishedCourseDesign();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillPreviousCourseElementsWithLastPublishedCourseDesign() {
|
private void fillPreviousCourseElementsWithLastPublishedCourseDesign() {
|
||||||
CourseBase lastPublishedCourseDesign = InMemoryDataStore.INSTANCE.getLastPublishedCourseDesign();
|
CourseBase lastPublishedCourseDesign = InMemoryDataStore.INSTANCE.getLastPublishedCourseDesign();
|
||||||
if(lastPublishedCourseDesign != null) {
|
if (lastPublishedCourseDesign != null) {
|
||||||
fillPreviousCourseElementsInList(lastPublishedCourseDesign);
|
fillPreviousCourseElementsInList(lastPublishedCourseDesign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadMarks() {
|
private void loadMarks() {
|
||||||
dataManager.loadMarks(getRace(), new LoadClient<Collection<Mark>>() {
|
Loader<?> marksLoader = getLoaderManager().restartLoader(MarksLoaderId, null,
|
||||||
|
dataManager.createMarksLoader(getRace(), new LoadClient<Collection<Mark>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFailed(Exception reason) {
|
public void onLoadFailed(Exception reason) {
|
||||||
|
Toast.makeText(getActivity(), String.format("Marks: %s",reason.toString()), Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadSucceded(Collection<Mark> data) {
|
public void onLoadSucceded(Collection<Mark> data, boolean isCached) {
|
||||||
onLoadMarksSucceeded(data);
|
onLoadMarksSucceeded(data);
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
});
|
// ignore any cached results and force a remote load of the marks,
|
||||||
|
// because we always need the most current.
|
||||||
|
marksLoader.forceLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onLoadMarksSucceeded(Collection<Mark> data) {
|
protected void onLoadMarksSucceeded(Collection<Mark> data) {
|
||||||
@@ -298,7 +280,7 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
|
|
||||||
if (controlPoint instanceof Mark) {
|
if (controlPoint instanceof Mark) {
|
||||||
CourseListDataElement element = new CourseListDataElement();
|
CourseListDataElement element = new CourseListDataElement();
|
||||||
element.setLeftMark((Mark)controlPoint);
|
element.setLeftMark((Mark) controlPoint);
|
||||||
element.setRoundingDirection(getRoundingDirection(waypoint.getPassingSide()));
|
element.setRoundingDirection(getRoundingDirection(waypoint.getPassingSide()));
|
||||||
elementList.add(element);
|
elementList.add(element);
|
||||||
} else if (controlPoint instanceof Gate) {
|
} else if (controlPoint instanceof Gate) {
|
||||||
@@ -327,23 +309,27 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected CourseBase convertCourseElementsToACourseData() throws IllegalStateException, IllegalArgumentException {
|
protected CourseBase convertCourseElementsToACourseData() throws IllegalStateException, IllegalArgumentException {
|
||||||
//TODO find a proper name for the highly flexible ESS courses to be shown on the regatta overview page
|
// TODO find a proper name for the highly flexible ESS courses to be shown on the regatta overview page
|
||||||
CourseBase design = new CourseDataImpl("Course template");
|
CourseBase design = new CourseDataImpl("Course");
|
||||||
List<Waypoint> waypoints = new ArrayList<Waypoint>();
|
List<Waypoint> waypoints = new ArrayList<Waypoint>();
|
||||||
|
|
||||||
for (CourseListDataElement courseElement : courseElements) {
|
for (CourseListDataElement courseElement : courseElements) {
|
||||||
if (courseElement.getRoundingDirection().equals(RoundingDirection.Gate) && courseElement.getRightMark() != null) {
|
if (courseElement.getRoundingDirection().equals(RoundingDirection.Gate)
|
||||||
String gateName = "Gate " + courseElement.getLeftMark().getName() + " / " + courseElement.getRightMark().getName();
|
&& courseElement.getRightMark() != null) {
|
||||||
|
String gateName = "Gate " + courseElement.getLeftMark().getName() + " / "
|
||||||
|
+ courseElement.getRightMark().getName();
|
||||||
Gate gate = new GateImpl(courseElement.getLeftMark(), courseElement.getRightMark(), gateName);
|
Gate gate = new GateImpl(courseElement.getLeftMark(), courseElement.getRightMark(), gateName);
|
||||||
Waypoint waypoint = new WaypointImpl(gate);
|
Waypoint waypoint = new WaypointImpl(gate);
|
||||||
|
|
||||||
waypoints.add(waypoint);
|
waypoints.add(waypoint);
|
||||||
} else if (courseElement.getRoundingDirection().equals(RoundingDirection.Gate) && courseElement.getRightMark() == null) {
|
} else if (courseElement.getRoundingDirection().equals(RoundingDirection.Gate)
|
||||||
|
&& courseElement.getRightMark() == null) {
|
||||||
throw new IllegalStateException("Gate has no right buoy");
|
throw new IllegalStateException("Gate has no right buoy");
|
||||||
} else if (courseElement.getRoundingDirection().equals(RoundingDirection.None)) {
|
} else if (courseElement.getRoundingDirection().equals(RoundingDirection.None)) {
|
||||||
throw new IllegalStateException("Each waypoints needs a passing side");
|
throw new IllegalStateException("Each waypoints needs a passing side");
|
||||||
} else {
|
} else {
|
||||||
Waypoint waypoint = new WaypointImpl(courseElement.getLeftMark(), getNauticalSide(courseElement.getRoundingDirection()));
|
Waypoint waypoint = new WaypointImpl(courseElement.getLeftMark(),
|
||||||
|
getNauticalSide(courseElement.getRoundingDirection()));
|
||||||
|
|
||||||
waypoints.add(waypoint);
|
waypoints.add(waypoint);
|
||||||
}
|
}
|
||||||
@@ -365,7 +351,7 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
NauticalSide side = null;
|
NauticalSide side = null;
|
||||||
if (roundingDirection.name().equalsIgnoreCase(NauticalSide.PORT.name())) {
|
if (roundingDirection.name().equalsIgnoreCase(NauticalSide.PORT.name())) {
|
||||||
side = NauticalSide.PORT;
|
side = NauticalSide.PORT;
|
||||||
} else if (roundingDirection.name().equalsIgnoreCase(NauticalSide.STARBOARD.name())){
|
} else if (roundingDirection.name().equalsIgnoreCase(NauticalSide.STARBOARD.name())) {
|
||||||
side = NauticalSide.STARBOARD;
|
side = NauticalSide.STARBOARD;
|
||||||
}
|
}
|
||||||
return side;
|
return side;
|
||||||
@@ -377,7 +363,7 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
direction = RoundingDirection.None;
|
direction = RoundingDirection.None;
|
||||||
} else if (passingSide.name().equalsIgnoreCase(RoundingDirection.Port.name())) {
|
} else if (passingSide.name().equalsIgnoreCase(RoundingDirection.Port.name())) {
|
||||||
direction = RoundingDirection.Port;
|
direction = RoundingDirection.Port;
|
||||||
} else if (passingSide.name().equalsIgnoreCase(RoundingDirection.Starboard.name())){
|
} else if (passingSide.name().equalsIgnoreCase(RoundingDirection.Starboard.name())) {
|
||||||
direction = RoundingDirection.Starboard;
|
direction = RoundingDirection.Starboard;
|
||||||
} else {
|
} else {
|
||||||
direction = RoundingDirection.Gate;
|
direction = RoundingDirection.Gate;
|
||||||
@@ -400,7 +386,7 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
//do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.create();
|
builder.create();
|
||||||
@@ -411,7 +397,7 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
courseElements.clear();
|
courseElements.clear();
|
||||||
courseElements.addAll(previousCourseElements);
|
courseElements.addAll(previousCourseElements);
|
||||||
courseElementAdapter.notifyDataSetChanged();
|
courseElementAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onMarkClickedOnGrid(Mark mark) {
|
protected void onMarkClickedOnGrid(Mark mark) {
|
||||||
if (courseElements.isEmpty()) {
|
if (courseElements.isEmpty()) {
|
||||||
@@ -429,7 +415,8 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
|
|
||||||
private CourseListDataElement getFirstGateCourseElementWithoutRightMark() {
|
private CourseListDataElement getFirstGateCourseElementWithoutRightMark() {
|
||||||
for (CourseListDataElement courseElement : courseElements) {
|
for (CourseListDataElement courseElement : courseElements) {
|
||||||
if (courseElement.getRoundingDirection().equals(RoundingDirection.Gate) && courseElement.getRightMark() == null) {
|
if (courseElement.getRoundingDirection().equals(RoundingDirection.Gate)
|
||||||
|
&& courseElement.getRightMark() == null) {
|
||||||
return courseElement;
|
return courseElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,11 +435,9 @@ public class ESSCourseDesignDialogFragment extends RaceDialogFragment {
|
|||||||
directions.add(direction.name());
|
directions.add(direction.name());
|
||||||
}
|
}
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setTitle(R.string.pick_a_rounding_direction)
|
builder.setTitle(R.string.pick_a_rounding_direction).setItems(R.array.rounding_directions,
|
||||||
.setItems(R.array.rounding_directions, new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int position) {
|
public void onClick(DialogInterface dialog, int position) {
|
||||||
// for i18n we expect following order in array: 1. Port, 2. Starboard, 3. Gate
|
|
||||||
//String[] directions = getActivity().getResources().getStringArray(R.array.rounding_directions);
|
|
||||||
RoundingDirection pickedDirection = RoundingDirection.relevantValues()[position];
|
RoundingDirection pickedDirection = RoundingDirection.relevantValues()[position];
|
||||||
onRoundingDirectionPicked(courseElement, pickedDirection);
|
onRoundingDirectionPicked(courseElement, pickedDirection);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
|||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
|
||||||
public abstract class FragmentAttachedDialogFragment extends BaseDialogFragment {
|
public abstract class FragmentAttachedDialogFragment extends AttachedDialogFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DialogListenerHost getHost() {
|
protected DialogListenerHost getHost() {
|
||||||
|
|||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
||||||
|
|
||||||
|
import android.app.DialogFragment;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.sap.sailing.racecommittee.app.logging.LifecycleLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple base class for {@link DialogFragment}'s to add some logging.
|
||||||
|
*/
|
||||||
|
public abstract class LoggableDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
private LifecycleLogger lifeLogger;
|
||||||
|
|
||||||
|
public LoggableDialogFragment() {
|
||||||
|
this.lifeLogger = new LifecycleLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
lifeLogger.onCreate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
lifeLogger.onStart(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
lifeLogger.onResume(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
lifeLogger.onPause(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
lifeLogger.onStop(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
lifeLogger.onDestroy(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+42
-19
@@ -9,6 +9,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Loader;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -19,6 +20,7 @@ import android.widget.AdapterView.OnItemClickListener;
|
|||||||
import android.widget.AdapterView.OnItemLongClickListener;
|
import android.widget.AdapterView.OnItemLongClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.mobeta.android.dslv.DragSortController;
|
import com.mobeta.android.dslv.DragSortController;
|
||||||
import com.mobeta.android.dslv.DragSortListView;
|
import com.mobeta.android.dslv.DragSortListView;
|
||||||
@@ -29,6 +31,7 @@ import com.sap.sailing.domain.common.impl.Util;
|
|||||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||||
import com.sap.sailing.racecommittee.app.R;
|
import com.sap.sailing.racecommittee.app.R;
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
|
||||||
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
|
||||||
import com.sap.sailing.racecommittee.app.domain.impl.DomainFactoryImpl;
|
import com.sap.sailing.racecommittee.app.domain.impl.DomainFactoryImpl;
|
||||||
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
import com.sap.sailing.racecommittee.app.logging.ExLog;
|
||||||
@@ -93,7 +96,8 @@ public class PositioningFragment extends RaceDialogFragment {
|
|||||||
|
|
||||||
positionedCompetitors = initializeFinishPositioningList();
|
positionedCompetitors = initializeFinishPositioningList();
|
||||||
deletePositionedCompetitorsFromUnpositionedList();
|
deletePositionedCompetitorsFromUnpositionedList();
|
||||||
positioningAdapter = new CompetitorPositioningListAdapter(getActivity(), R.layout.welter_positioning_item, positionedCompetitors);
|
positioningAdapter = new CompetitorPositioningListAdapter(getActivity(), R.layout.welter_positioning_item,
|
||||||
|
positionedCompetitors);
|
||||||
|
|
||||||
positioningListView = (DragSortListView) getView().findViewById(R.id.dragSortListPositioning);
|
positioningListView = (DragSortListView) getView().findViewById(R.id.dragSortListPositioning);
|
||||||
positioningListView.setAdapter(positioningAdapter);
|
positioningListView.setAdapter(positioningAdapter);
|
||||||
@@ -139,18 +143,13 @@ public class PositioningFragment extends RaceDialogFragment {
|
|||||||
|
|
||||||
public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
|
public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
|
||||||
Competitor competitor = (Competitor) competitorsAdapter.getItem(position);
|
Competitor competitor = (Competitor) competitorsAdapter.getItem(position);
|
||||||
ExLog.i("RaceFinishingFragment", "Grid is clicked at position " + position + " for competitor " + competitor.getName());
|
ExLog.i("RaceFinishingFragment", "Grid is clicked at position " + position + " for competitor "
|
||||||
|
+ competitor.getName());
|
||||||
onCompetitorClickedOnGrid(competitor);
|
onCompetitorClickedOnGrid(competitor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
onLoadCompetitorsSucceeded(getRace().getCompetitors());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a DragSortController and thereby defines the behaviour of the drag sort list
|
* Creates a DragSortController and thereby defines the behaviour of the drag sort list
|
||||||
*/
|
*/
|
||||||
@@ -167,30 +166,50 @@ public class PositioningFragment extends RaceDialogFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadCompetitors() {
|
private void loadCompetitors() {
|
||||||
|
getActivity().setProgressBarIndeterminateVisibility(true);
|
||||||
OnlineDataManager.create(getActivity()).loadCompetitors(getRace(), new LoadClient<Collection<Competitor>>() {
|
ReadonlyDataManager dataManager = OnlineDataManager.create(getActivity());
|
||||||
|
Loader<?> competitorLoaders = getLoaderManager().initLoader(0, null,
|
||||||
|
dataManager.createCompetitorsLoader(getRace(), new LoadClient<Collection<Competitor>>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFailed(Exception reason) {
|
public void onLoadFailed(Exception reason) {
|
||||||
onLoadCompetitorsSucceeded(getRace().getCompetitors());
|
getActivity().setProgressBarIndeterminateVisibility(false);
|
||||||
|
Toast.makeText(getActivity(), String.format("Competitors: %s", reason.toString()),
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadSucceded(Collection<Competitor> data) {
|
public void onLoadSucceded(Collection<Competitor> data, boolean isCached) {
|
||||||
|
if (!isCached) {
|
||||||
|
getActivity().setProgressBarIndeterminateVisibility(false);
|
||||||
|
}
|
||||||
onLoadCompetitorsSucceeded(data);
|
onLoadCompetitorsSucceeded(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}));
|
||||||
|
// Force load to get non-cached remote competitors...
|
||||||
|
competitorLoaders.forceLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onLoadCompetitorsSucceeded(Collection<Competitor> data) {
|
protected void onLoadCompetitorsSucceeded(Collection<Competitor> data) {
|
||||||
competitors.clear();
|
competitors.clear();
|
||||||
competitors.addAll(data);
|
competitors.addAll(data);
|
||||||
Collections.sort(competitors, competitorComparator);
|
Collections.sort(competitors, competitorComparator);
|
||||||
|
deleteObsoleteCompetitorsFromPositionedList(data);
|
||||||
deletePositionedCompetitorsFromUnpositionedList();
|
deletePositionedCompetitorsFromUnpositionedList();
|
||||||
competitorsAdapter.notifyDataSetChanged();
|
competitorsAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void deleteObsoleteCompetitorsFromPositionedList(Collection<Competitor> validCompetitors) {
|
||||||
|
List<Triple<Serializable, String, MaxPointsReason>> toBeDeleted = new ArrayList<Util.Triple<Serializable, String, MaxPointsReason>>();
|
||||||
|
for (Triple<Serializable, String, MaxPointsReason> positionedItem : positionedCompetitors) {
|
||||||
|
if (!validCompetitors.contains(DomainFactoryImpl.INSTANCE.getExistingCompetitorById(positionedItem.getA()))) {
|
||||||
|
toBeDeleted.add(positionedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
positionedCompetitors.removeAll(toBeDeleted);
|
||||||
|
}
|
||||||
|
|
||||||
private void deletePositionedCompetitorsFromUnpositionedList() {
|
private void deletePositionedCompetitorsFromUnpositionedList() {
|
||||||
for (Triple<Serializable, String, MaxPointsReason> positionedItem : positionedCompetitors) {
|
for (Triple<Serializable, String, MaxPointsReason> positionedItem : positionedCompetitors) {
|
||||||
Competitor competitor = DomainFactoryImpl.INSTANCE.getExistingCompetitorById(positionedItem.getA());
|
Competitor competitor = DomainFactoryImpl.INSTANCE.getExistingCompetitorById(positionedItem.getA());
|
||||||
@@ -216,8 +235,8 @@ public class PositioningFragment extends RaceDialogFragment {
|
|||||||
private void createMaxPointsReasonSelectionDialog(final Triple<Serializable, String, MaxPointsReason> item) {
|
private void createMaxPointsReasonSelectionDialog(final Triple<Serializable, String, MaxPointsReason> item) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
final CharSequence[] maxPointsReasons = getAllMaxPointsReasons();
|
final CharSequence[] maxPointsReasons = getAllMaxPointsReasons();
|
||||||
builder.setTitle(R.string.select_penalty_reason)
|
builder.setTitle(R.string.select_penalty_reason).setItems(maxPointsReasons,
|
||||||
.setItems(maxPointsReasons, new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int position) {
|
public void onClick(DialogInterface dialog, int position) {
|
||||||
setMaxPointsReasonForItem(item, maxPointsReasons[position]);
|
setMaxPointsReasonForItem(item, maxPointsReasons[position]);
|
||||||
}
|
}
|
||||||
@@ -234,9 +253,11 @@ public class PositioningFragment extends RaceDialogFragment {
|
|||||||
return result.toArray(new CharSequence[result.size()]);
|
return result.toArray(new CharSequence[result.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setMaxPointsReasonForItem(Triple<Serializable, String, MaxPointsReason> item, CharSequence maxPointsReasonName) {
|
protected void setMaxPointsReasonForItem(Triple<Serializable, String, MaxPointsReason> item,
|
||||||
|
CharSequence maxPointsReasonName) {
|
||||||
MaxPointsReason maxPointsReason = MaxPointsReason.valueOf(maxPointsReasonName.toString());
|
MaxPointsReason maxPointsReason = MaxPointsReason.valueOf(maxPointsReasonName.toString());
|
||||||
Triple<Serializable, String, MaxPointsReason> newItem = new Triple<Serializable, String, MaxPointsReason>(item.getA(), item.getB(), maxPointsReason);
|
Triple<Serializable, String, MaxPointsReason> newItem = new Triple<Serializable, String, MaxPointsReason>(
|
||||||
|
item.getA(), item.getB(), maxPointsReason);
|
||||||
int currentIndexOfItem = positionedCompetitors.indexOf(item);
|
int currentIndexOfItem = positionedCompetitors.indexOf(item);
|
||||||
replaceItemInPositioningList(currentIndexOfItem, item, newItem);
|
replaceItemInPositioningList(currentIndexOfItem, item, newItem);
|
||||||
|
|
||||||
@@ -246,7 +267,8 @@ public class PositioningFragment extends RaceDialogFragment {
|
|||||||
getRace().getState().setFinishPositioningListChanged(positionedCompetitors);
|
getRace().getState().setFinishPositioningListChanged(positionedCompetitors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceItemInPositioningList(int currentIndexOfItem, Triple<Serializable, String, MaxPointsReason> item, Triple<Serializable, String, MaxPointsReason> newItem) {
|
private void replaceItemInPositioningList(int currentIndexOfItem,
|
||||||
|
Triple<Serializable, String, MaxPointsReason> item, Triple<Serializable, String, MaxPointsReason> newItem) {
|
||||||
positioningAdapter.remove(item);
|
positioningAdapter.remove(item);
|
||||||
positioningAdapter.insert(newItem, currentIndexOfItem);
|
positioningAdapter.insert(newItem, currentIndexOfItem);
|
||||||
}
|
}
|
||||||
@@ -271,7 +293,8 @@ public class PositioningFragment extends RaceDialogFragment {
|
|||||||
|
|
||||||
private void addNewCompetitorToPositioningList(Competitor competitor) {
|
private void addNewCompetitorToPositioningList(Competitor competitor) {
|
||||||
|
|
||||||
positionedCompetitors.add(new Triple<Serializable, String, MaxPointsReason>(competitor.getId(), competitor.getName(), MaxPointsReason.NONE));
|
positionedCompetitors.add(new Triple<Serializable, String, MaxPointsReason>(competitor.getId(), competitor
|
||||||
|
.getName(), MaxPointsReason.NONE));
|
||||||
positioningAdapter.notifyDataSetChanged();
|
positioningAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -28,7 +28,7 @@ import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
|
|||||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
import com.sap.sailing.racecommittee.app.domain.impl.BoatClassSeriesFleet;
|
import com.sap.sailing.racecommittee.app.domain.impl.BoatClassSeriesFleet;
|
||||||
|
|
||||||
public class ProtestTimeDialogFragment extends BaseDialogFragment {
|
public class ProtestTimeDialogFragment extends AttachedDialogFragment {
|
||||||
|
|
||||||
private static String ARGS_RACE_IDS = ProtestTimeDialogFragment.class.getSimpleName() + ".raceids";
|
private static String ARGS_RACE_IDS = ProtestTimeDialogFragment.class.getSimpleName() + ".raceids";
|
||||||
|
|
||||||
@@ -84,12 +84,12 @@ public class ProtestTimeDialogFragment extends BaseDialogFragment {
|
|||||||
public DialogResultListener getListener() {
|
public DialogResultListener getListener() {
|
||||||
return new DialogResultListener() {
|
return new DialogResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDialogNegativeButton(BaseDialogFragment dialog) {
|
public void onDialogNegativeButton(AttachedDialogFragment dialog) {
|
||||||
// no operation
|
// no operation
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDialogPositiveButton(BaseDialogFragment dialog) {
|
public void onDialogPositiveButton(AttachedDialogFragment dialog) {
|
||||||
setAndAnnounceProtestTime();
|
setAndAnnounceProtestTime();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-8
@@ -40,7 +40,7 @@ public class RaceChooseCourseByLabelDialog extends RaceDialogFragment {
|
|||||||
holder.addView(rowLayout);
|
holder.addView(rowLayout);
|
||||||
for (int round = minNumberOfRounds; round <= maxNumberOfRounds; round++) {
|
for (int round = minNumberOfRounds; round <= maxNumberOfRounds; round++) {
|
||||||
Button courseButton = new Button(getActivity());
|
Button courseButton = new Button(getActivity());
|
||||||
courseButton.setText(courseNumberAndName[0]+" "+round);
|
courseButton.setText(courseNumberAndName[0] + " " + round);
|
||||||
courseButton.setOnClickListener( new OnClickListener() {
|
courseButton.setOnClickListener( new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -56,8 +56,6 @@ public class RaceChooseCourseByLabelDialog extends RaceDialogFragment {
|
|||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
@@ -75,9 +73,4 @@ public class RaceChooseCourseByLabelDialog extends RaceDialogFragment {
|
|||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyTick() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+3
-4
@@ -2,16 +2,15 @@ package com.sap.sailing.racecommittee.app.ui.fragments.dialogs;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
import com.sap.sailing.racecommittee.app.AppConstants;
|
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||||
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
|
||||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||||
import com.sap.sailing.racecommittee.app.utils.TickListener;
|
import com.sap.sailing.racecommittee.app.utils.TickListener;
|
||||||
import com.sap.sailing.racecommittee.app.utils.TickSingleton;
|
import com.sap.sailing.racecommittee.app.utils.TickSingleton;
|
||||||
|
|
||||||
import android.app.DialogFragment;
|
public abstract class RaceDialogFragment extends LoggableDialogFragment implements TickListener {
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
public abstract class RaceDialogFragment extends DialogFragment implements TickListener {
|
|
||||||
|
|
||||||
public static Bundle createArguments(ManagedRace race) {
|
public static Bundle createArguments(ManagedRace race) {
|
||||||
Bundle arguments = new Bundle();
|
Bundle arguments = new Bundle();
|
||||||
|
|||||||
+5
-8
@@ -2,8 +2,10 @@ package com.sap.sailing.racecommittee.app.ui.fragments.lists;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.LoaderManager.LoaderCallbacks;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
@@ -11,6 +13,7 @@ import com.sap.sailing.domain.base.CourseArea;
|
|||||||
import com.sap.sailing.racecommittee.app.AppConstants;
|
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||||
import com.sap.sailing.racecommittee.app.R;
|
import com.sap.sailing.racecommittee.app.R;
|
||||||
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
|
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
|
||||||
|
import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderResult;
|
||||||
import com.sap.sailing.racecommittee.app.ui.adapters.CourseAreaArrayAdapter;
|
import com.sap.sailing.racecommittee.app.ui.adapters.CourseAreaArrayAdapter;
|
||||||
import com.sap.sailing.racecommittee.app.ui.adapters.NamedArrayAdapter;
|
import com.sap.sailing.racecommittee.app.ui.adapters.NamedArrayAdapter;
|
||||||
import com.sap.sailing.racecommittee.app.ui.fragments.lists.selection.CourseAreaSelectedListenerHost;
|
import com.sap.sailing.racecommittee.app.ui.fragments.lists.selection.CourseAreaSelectedListenerHost;
|
||||||
@@ -27,12 +30,6 @@ public class CourseAreaListFragment extends NamedListFragment<CourseArea> {
|
|||||||
this.parentEventId = getArguments().getSerializable(AppConstants.EventIdTag);
|
this.parentEventId = getArguments().getSerializable(AppConstants.EventIdTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
loadItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NamedArrayAdapter<CourseArea> createAdapter(Context context, ArrayList<CourseArea> items) {
|
protected NamedArrayAdapter<CourseArea> createAdapter(Context context, ArrayList<CourseArea> items) {
|
||||||
return new CourseAreaArrayAdapter(context, items);
|
return new CourseAreaArrayAdapter(context, items);
|
||||||
@@ -55,8 +52,8 @@ public class CourseAreaListFragment extends NamedListFragment<CourseArea> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadItems(ReadonlyDataManager manager) {
|
protected LoaderCallbacks<DataLoaderResult<Collection<CourseArea>>> createLoaderCallbacks(ReadonlyDataManager manager) {
|
||||||
manager.loadCourseAreas(parentEventId, this);
|
return manager.createCourseAreasLoader(parentEventId, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loaded 100 of 108 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user