# working towards implementing the RacingProcedureConfiguration

This commit is contained in:
Lukas Niemeier committed 2013-11-22 01:27:26 +01:00
1 parent 0a06954ed3
commit e0f2309b16
44 files changed
+524 -183

No files matched your search

@@ -14,7 +14,7 @@ import org.junit.Test;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.racelog.Flags;
@@ -38,7 +38,7 @@ public class RaceStateTest {
private RaceLogEventAuthor author;
private RaceLogEventFactory factory;
private RacingProcedureType defaultRacingProcedureType;
private StoreableConfiguration<RacingProceduresConfiguration> configuration;
private ConfigurationLoader<RacingProceduresConfiguration> configuration;
private RaceStateChangedListener listener;
private TimePoint nowMock;
@@ -51,7 +51,7 @@ public class RaceStateTest {
author = new RaceLogEventAuthorImpl("Test", 1);
factory = RaceLogEventFactory.INSTANCE;
defaultRacingProcedureType = RacingProcedureType.RRS26;
configuration = mock(StoreableConfiguration.class);
configuration = mock(ConfigurationLoader.class);
listener = mock(RaceStateChangedListener.class);
nowMock = mock(TimePoint.class);
@@ -0,0 +1,20 @@
package com.sap.sailing.domain.base.configuration;
/**
* Capable of loading and storing a {@link ConfigurationType}.
*/
public interface ConfigurationLoader<ConfigurationType> {
/**
* Loads the configuration from its database.
* @return A final copy of {@link ConfigurationType} after loading.
*/
ConfigurationType load();
/**
* Saves the configuration to its database.
*/
void store();
}
@@ -0,0 +1,16 @@
package com.sap.sailing.domain.base.configuration;
import java.io.Serializable;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.racelog.state.racingprocedure.RacingProcedure;
/**
* Interface holding configuration options common to all {@link RacingProcedure}s.
*/
public interface RacingProcedureConfiguration extends Serializable {
Flags getClassFlag();
Boolean hasInidividualRecall();
}
@@ -1,20 +0,0 @@
package com.sap.sailing.domain.base.configuration;
/**
* A {@link ConfigurationType} which is backed by some database. Provides methods to reload and save.
*/
public interface StoreableConfiguration<ConfigurationType> {
/**
* Reloads the configuration.
* @return A copy of this {@link ConfigurationType} after loading.
*/
ConfigurationType load();
/**
* Saves the configuration
*/
void store();
}
@@ -80,8 +80,12 @@ public class DeviceConfigurationImpl implements DeviceConfiguration {
this.byNameDesignerCourseNames = byNameDesignerCourseNames;
}
protected static DeviceConfiguration copy(DeviceConfiguration configuration) {
DeviceConfigurationImpl copyConfiguration = new DeviceConfigurationImpl(configuration.getRacingProceduresConfiguration());
protected DeviceConfiguration copy() {
DeviceConfigurationImpl copyConfiguration = new DeviceConfigurationImpl(proceduresConfiguration);
copyConfiguration.setAllowedCourseAreaNames(allowedCourseAreaNames);
copyConfiguration.setByNameDesignerCourseNames(byNameDesignerCourseNames);
copyConfiguration.setDefaultCourseDesignerMode(defaultCourseDesignerMode);
copyConfiguration.setResultsMailRecipient(resultsMailRecipient);
return copyConfiguration;
}
@@ -1,19 +1,19 @@
package com.sap.sailing.domain.base.configuration.impl;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
/**
* Is empty, does nothing;
* Is empty, does nothing on store and load.
*/
public class EmptyConfiguration extends RacingProceduresConfigurationImpl implements
StoreableConfiguration<RacingProceduresConfiguration> {
public class EmptyRacingProceduresConfiguration extends RacingProceduresConfigurationImpl implements
ConfigurationLoader<RacingProceduresConfiguration> {
private static final long serialVersionUID = -4187341706420504456L;
@Override
public RacingProceduresConfiguration load() {
return super.copy(this);
return copy();
}
@Override
@@ -1,14 +1,56 @@
package com.sap.sailing.domain.base.configuration.impl;
import java.util.List;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.common.racelog.Flags;
public class RacingProceduresConfigurationImpl implements RacingProceduresConfiguration {
private static final long serialVersionUID = 8501755084811977792L;
protected static RacingProceduresConfiguration copy(RacingProceduresConfiguration configuration) {
RacingProceduresConfiguration copyConfiguration = new RacingProceduresConfigurationImpl();
return copyConfiguration;
private Flags classFlag;
private Boolean hasInidividualRecall;
private List<Flags> startModeFlags;
// GENERAL
@Override
public Flags getClassFlag() {
return classFlag;
}
public void setClassFlag(Flags classFlag) {
this.classFlag = classFlag;
}
@Override
public Boolean hasInidividualRecall() {
return hasInidividualRecall;
}
public void setHasInidividualRecall(Boolean hasInidividualRecall) {
this.hasInidividualRecall = hasInidividualRecall;
}
// RRS26
@Override
public List<Flags> getStartModeFlags() {
return startModeFlags;
}
public void setStartModeFlags(List<Flags> flags) {
this.startModeFlags = flags;
}
protected RacingProceduresConfiguration copy() {
RacingProceduresConfigurationImpl copy = new RacingProceduresConfigurationImpl();
copy.setClassFlag(classFlag);
copy.setHasInidividualRecall(hasInidividualRecall);
copy.setStartModeFlags(startModeFlags);
return copy;
}
}
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.base.configuration.procedures;
public interface ESSConfiguration {
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
public interface ESSConfiguration extends RacingProcedureConfiguration {
}
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.base.configuration.procedures;
public interface GateStartConfiguration {
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
public interface GateStartConfiguration extends RacingProcedureConfiguration {
}
@@ -1,5 +1,12 @@
package com.sap.sailing.domain.base.configuration.procedures;
public interface RRS26Configuration {
import java.util.List;
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
import com.sap.sailing.domain.common.racelog.Flags;
public interface RRS26Configuration extends RacingProcedureConfiguration {
List<Flags> getStartModeFlags();
}
@@ -11,8 +11,10 @@ import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
public class RRS26StartModeFlagFinder extends RaceLogAnalyzer<Flags> {
private final List<Flags> startModeFlags = Arrays.asList(Flags.PAPA, Flags.ZULU, Flags.BLACK, Flags.INDIA);
private RacingProcedureTypeAnalyzer procedureAnalyzer;
private final static List<Flags> defaultStartModeFlags = Arrays.asList(Flags.PAPA, Flags.ZULU, Flags.BLACK, Flags.INDIA);
private final RacingProcedureTypeAnalyzer procedureAnalyzer;
private final List<Flags> startModeFlags;
/**
* Searches for the start mode flag of a RRS26 race.
@@ -22,11 +24,16 @@ public class RRS26StartModeFlagFinder extends RaceLogAnalyzer<Flags> {
* {@link IllegalArgumentException} is thrown.
*/
public RRS26StartModeFlagFinder(RacingProcedureTypeAnalyzer procedureAnalyzer, RaceLog raceLog) {
this(procedureAnalyzer, raceLog, defaultStartModeFlags);
}
public RRS26StartModeFlagFinder(RacingProcedureTypeAnalyzer procedureAnalyzer, RaceLog raceLog, List<Flags> startModeFlags) {
super(raceLog);
if (raceLog != procedureAnalyzer.getRaceLog()) {
throw new IllegalArgumentException("Both analyzers must operate on the same race log.");
}
this.procedureAnalyzer = procedureAnalyzer;
this.startModeFlags = startModeFlags;
}
@Override
@@ -2,8 +2,8 @@ package com.sap.sailing.domain.racelog.state.impl;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.impl.EmptyConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.configuration.impl.EmptyRacingProceduresConfiguration;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
@@ -29,13 +29,13 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
* Creates a {@link RaceState} with the initial racing procedure type set to a fallback value and an empty configuration.
*/
public static RaceState create(RaceLog raceLog, RaceLogEventAuthor author) {
return create(raceLog, author, RaceStateImpl.FallbackInitialProcedureType, new EmptyConfiguration());
return create(raceLog, author, RaceStateImpl.FallbackInitialProcedureType, new EmptyRacingProceduresConfiguration());
}
/**
* Creates a {@link RaceState} with the initial racing procedure type set to a fallback value.
*/
public static RaceState create(RaceLog raceLog, RaceLogEventAuthor author, StoreableConfiguration<RacingProceduresConfiguration> configuration) {
public static RaceState create(RaceLog raceLog, RaceLogEventAuthor author, ConfigurationLoader<RacingProceduresConfiguration> configuration) {
return create(raceLog, author, RaceStateImpl.FallbackInitialProcedureType, configuration);
}
@@ -43,7 +43,7 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
* Creates a {@link RaceState}.
*/
public static RaceState create(RaceLog raceLog, RaceLogEventAuthor author, RacingProcedureType initalRacingProcedureType,
StoreableConfiguration<RacingProceduresConfiguration> configuration) {
ConfigurationLoader<RacingProceduresConfiguration> configuration) {
return new RaceStateImpl(raceLog, author,
RaceLogEventFactory.INSTANCE,
initalRacingProcedureType,
@@ -1,7 +1,7 @@
package com.sap.sailing.domain.racelog.state.impl;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.configuration.impl.EmptyConfiguration;
import com.sap.sailing.domain.base.configuration.impl.EmptyRacingProceduresConfiguration;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
@@ -45,7 +45,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
*/
public static ReadonlyRaceState create(RaceLog raceLog) {
return new ReadonlyRaceStateImpl(raceLog, ReadonlyRaceStateImpl.FallbackInitialProcedureType,
new ReadonlyRacingProcedureFactory(new EmptyConfiguration()));
new ReadonlyRacingProcedureFactory(new EmptyRacingProceduresConfiguration()));
}
protected final RaceLog raceLog;
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.racelog.state.racingprocedure;
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.racelog.RaceLog;
@@ -11,6 +12,7 @@ import com.sap.sailing.domain.racelog.state.ReadonlyRaceState;
public interface ReadonlyRacingProcedure extends RaceStateEventProcessor, RaceStateChangedListener {
RaceLog getRaceLog();
RacingProcedureType getType();
RacingProcedureConfiguration getConfiguration();
void addChangedListener(RacingProcedureChangedListener listener);
void removeChangedListener(RacingProcedureChangedListener listener);
@@ -36,7 +36,7 @@ public class ESSRacingProcedureImpl extends BaseRacingProcedure implements ESSRa
public ESSRacingProcedureImpl(RaceLog raceLog, RaceLogEventAuthor author,
RaceLogEventFactory factory, ESSConfiguration configuration) {
super(raceLog, author, factory);
super(raceLog, author, factory, configuration);
this.configuration = configuration;
update();
}
@@ -45,11 +45,6 @@ public class ESSRacingProcedureImpl extends BaseRacingProcedure implements ESSRa
public RacingProcedureType getType() {
return RacingProcedureType.ESS;
}
@Override
public boolean hasIndividualRecall() {
return true;
}
@Override
public RacingProcedurePrerequisite checkPrerequisitesForStart(TimePoint startTime, TimePoint now) {
@@ -151,5 +146,15 @@ public class ESSRacingProcedureImpl extends BaseRacingProcedure implements ESSRa
}
return null;
}
@Override
protected boolean hasIndividualRecallByDefault() {
return true;
}
@Override
public ESSConfiguration getConfiguration() {
return (ESSConfiguration) super.getConfiguration();
}
}
@@ -43,7 +43,7 @@ public class GateStartRacingProcedureImpl extends BaseRacingProcedure implements
public GateStartRacingProcedureImpl(RaceLog raceLog, RaceLogEventAuthor author,
RaceLogEventFactory factory, GateStartConfiguration configuration) {
super(raceLog, author, factory);
super(raceLog, author, factory, configuration);
this.configuration = configuration;
this.gateLineOpeningTimeAnalyzer = new GateLineOpeningTimeFinder(raceLog);
this.pathfinderAnalyzer = new PathfinderFinder(raceLog);
@@ -59,7 +59,7 @@ public class GateStartRacingProcedureImpl extends BaseRacingProcedure implements
}
@Override
public boolean hasIndividualRecall() {
protected boolean hasIndividualRecallByDefault() {
return false;
}
@@ -212,6 +212,11 @@ public class GateStartRacingProcedureImpl extends BaseRacingProcedure implements
super.update();
}
@Override
public GateStartConfiguration getConfiguration() {
return (GateStartConfiguration) super.getConfiguration();
}
private void rescheduleGateShutdownTime(TimePoint startTime) {
unscheduleStateEvent(RaceStateEvents.GATE_SHUTDOWN);
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.racelog.state.racingprocedure.impl;
import java.util.Arrays;
import java.util.Collection;
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.racelog.RaceLog;
@@ -40,6 +41,7 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
protected final RaceLog raceLog;
protected final RaceLogEventAuthor author;
protected final RaceLogEventFactory factory;
private final RacingProcedureConfiguration configuration;
private final RacingProcedureChangedListeners<? extends RacingProcedureChangedListener> changedListeners;
private final IsIndividualRecallDisplayedAnalyzer isRecallDisplayedAnalyzer;
@@ -51,10 +53,12 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
/**
* When calling me, call {@link BaseRacingProcedure#update()} afterwards!
*/
public BaseRacingProcedure(RaceLog raceLog, RaceLogEventAuthor author, RaceLogEventFactory factory) {
public BaseRacingProcedure(RaceLog raceLog, RaceLogEventAuthor author, RaceLogEventFactory factory,
RacingProcedureConfiguration configuration) {
this.raceLog = raceLog;
this.author = author;
this.factory = factory;
this.configuration = configuration;
this.changedListeners = createChangedListenerContainer();
this.isRecallDisplayedAnalyzer = new IsIndividualRecallDisplayedAnalyzer(raceLog);
@@ -153,6 +157,14 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
return false;
}
}
@Override
public boolean hasIndividualRecall() {
return configuration.hasInidividualRecall() == null ?
hasIndividualRecallByDefault() : configuration.hasInidividualRecall();
}
protected abstract boolean hasIndividualRecallByDefault();
@Override
public void eventAdded(RaceLogEvent event) {
@@ -195,6 +207,11 @@ public abstract class BaseRacingProcedure extends BaseRaceStateChangedListener i
scheduler.unscheduleStateEvent(raceStateEventName);
}
}
@Override
public RacingProcedureConfiguration getConfiguration() {
return configuration;
}
protected abstract Collection<RaceStateEvent> createStartStateEvents(TimePoint startTime);
@@ -1,7 +1,7 @@
package com.sap.sailing.domain.racelog.state.racingprocedure.impl;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
@@ -15,7 +15,7 @@ public class RacingProcedureFactoryImpl extends ReadonlyRacingProcedureFactory i
private final RaceLogEventFactory factory;
public RacingProcedureFactoryImpl(RaceLogEventAuthor author, RaceLogEventFactory factory,
StoreableConfiguration<RacingProceduresConfiguration> configuration) {
ConfigurationLoader<RacingProceduresConfiguration> configuration) {
super(configuration);
this.author = author;
this.factory = factory;
@@ -1,7 +1,7 @@
package com.sap.sailing.domain.racelog.state.racingprocedure.impl;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
@@ -16,9 +16,9 @@ import com.sap.sailing.domain.racelog.state.racingprocedure.rrs26.impl.RRS26Raci
public class ReadonlyRacingProcedureFactory implements RacingProcedureFactory {
protected final StoreableConfiguration<RacingProceduresConfiguration> configuration;
protected final ConfigurationLoader<RacingProceduresConfiguration> configuration;
public ReadonlyRacingProcedureFactory(StoreableConfiguration<RacingProceduresConfiguration> configuration) {
public ReadonlyRacingProcedureFactory(ConfigurationLoader<RacingProceduresConfiguration> configuration) {
this.configuration = configuration;
}
@@ -32,17 +32,19 @@ public class RRS26RacingProcedureImpl extends BaseRacingProcedure implements RRS
private final static long startPhaseStartModeUpInterval = 4 * 60 * 1000; // minutes * seconds * milliseconds
private final static long startPhaseStartModeDownInterval = 1 * 60 * 1000; // minutes * seconds * milliseconds
@SuppressWarnings("unused")
private final RRS26Configuration configuration;
private final RRS26StartModeFlagFinder startmodeFlagAnalyzer;
private final RRS26StartModeFlagFinder startModeFlagAnalyzer;
private Flags cachedStartmodeFlag;
public RRS26RacingProcedureImpl(RaceLog raceLog, RaceLogEventAuthor author,
RaceLogEventFactory factory, RRS26Configuration configuration) {
super(raceLog, author, factory);
this.configuration = configuration;
this.startmodeFlagAnalyzer = new RRS26StartModeFlagFinder(new RacingProcedureTypeAnalyzer(raceLog), raceLog);
super(raceLog, author, factory, configuration);
RacingProcedureTypeAnalyzer procedureAnalyzer = new RacingProcedureTypeAnalyzer(raceLog);
if (configuration.getStartModeFlags() != null) {
this.startModeFlagAnalyzer = new RRS26StartModeFlagFinder(procedureAnalyzer, raceLog, configuration.getStartModeFlags());
} else {
this.startModeFlagAnalyzer = new RRS26StartModeFlagFinder(procedureAnalyzer, raceLog);
}
this.cachedStartmodeFlag = ReadonlyRRS26RacingProcedure.DefaultStartMode;
update();
@@ -54,7 +56,7 @@ public class RRS26RacingProcedureImpl extends BaseRacingProcedure implements RRS
}
@Override
public boolean hasIndividualRecall() {
protected boolean hasIndividualRecallByDefault() {
return true;
}
@@ -155,12 +157,17 @@ public class RRS26RacingProcedureImpl extends BaseRacingProcedure implements RRS
@Override
protected void update() {
Flags startmodeFlag = startmodeFlagAnalyzer.analyze();
Flags startmodeFlag = startModeFlagAnalyzer.analyze();
if (startmodeFlag != null && !startmodeFlag.equals(cachedStartmodeFlag)) {
cachedStartmodeFlag = startmodeFlag;
getChangedListeners().onStartmodeChanged(this);
}
super.update();
}
@Override
public RRS26Configuration getConfiguration() {
return (RRS26Configuration) super.getConfiguration();
}
}
@@ -30,9 +30,13 @@ public class DeviceConfigurationJsonDeserializer implements JsonDeserializer<Dev
@Override
public DeviceConfiguration deserialize(JSONObject object) throws JsonDeserializationException {
JSONObject proceduresObject =
RacingProceduresConfiguration proceduresConfiguration = null;
if (object.containsKey(DeviceConfigurationJsonSerializer.FIELD_PROCEDURES_CONFIGURATION)) {
JSONObject proceduresObject =
Helpers.getNestedObjectSafe(object, DeviceConfigurationJsonSerializer.FIELD_PROCEDURES_CONFIGURATION);
RacingProceduresConfiguration proceduresConfiguration = proceduresDeserializer.deserialize(proceduresObject);
proceduresConfiguration = proceduresDeserializer.deserialize(proceduresObject);
}
DeviceConfigurationImpl configuration = createConfiguration(proceduresConfiguration);
@@ -1,17 +1,44 @@
package com.sap.sailing.server.gateway.deserialization.impl;
import java.util.ArrayList;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.impl.RacingProceduresConfigurationImpl;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.RacingProceduresConfigurationJsonSerializer;
public class RacingProceduresConfigurationJsonDeserializer implements JsonDeserializer<RacingProceduresConfiguration> {
@Override
public RacingProceduresConfiguration deserialize(JSONObject object) throws JsonDeserializationException {
RacingProceduresConfigurationImpl configuration = createConfiguration();
if (object.containsKey(RacingProceduresConfigurationJsonSerializer.FIELD_HAS_XRAY)) {
Boolean hasIndividualRecall = (Boolean) object.get(RacingProceduresConfigurationJsonSerializer.FIELD_HAS_XRAY);
configuration.setHasInidividualRecall(hasIndividualRecall);
}
if (object.containsKey(RacingProceduresConfigurationJsonSerializer.FIELD_CLASS_FLAG)) {
Flags classFlag = Flags.valueOf(object.get(RacingProceduresConfigurationJsonSerializer.FIELD_CLASS_FLAG).toString());
configuration.setClassFlag(classFlag);
}
if (object.containsKey(RacingProceduresConfigurationJsonSerializer.FIELD_START_MODE_FLAGS)) {
List<Flags> result = new ArrayList<Flags>();
JSONArray startModeFlags = Helpers.getNestedArraySafe(object,
RacingProceduresConfigurationJsonSerializer.FIELD_START_MODE_FLAGS);
for (Object startModeFlag : startModeFlags) {
result.add(Flags.valueOf(startModeFlag.toString()));
}
configuration.setStartModeFlags(result);
}
return configuration;
}
@@ -38,6 +38,7 @@ public class RaceGroupDeserializer implements JsonDeserializer<RaceGroup> {
if (object.containsKey(RaceGroupJsonSerializer.FIELD_COURSE_AREA)) {
// TODO: deserialize CourseArea ...
// WHY should I?
}
if (object.containsKey(RaceGroupJsonSerializer.FIELD_BOAT_CLASS)) {
@@ -1,15 +1,35 @@
package com.sap.sailing.server.gateway.serialization.impl;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class RacingProceduresConfigurationJsonSerializer implements JsonSerializer<RacingProceduresConfiguration> {
public static final String FIELD_CLASS_FLAG = "classFlag";
public static final String FIELD_START_MODE_FLAGS = "startModeFlags";
public static final String FIELD_HAS_XRAY = "hasIndividualRecall";
@Override
public JSONObject serialize(RacingProceduresConfiguration object) {
JSONObject result = new JSONObject();
if (object.hasInidividualRecall() != null) {
result.put(FIELD_HAS_XRAY, object.hasInidividualRecall());
}
if (object.getClassFlag() != null) {
result.put(FIELD_CLASS_FLAG, object.getClassFlag().name());
}
if (object.getStartModeFlags() != null) {
JSONArray startModeFlags = new JSONArray();
for (Flags startModeFlag : object.getStartModeFlags()) {
startModeFlags.add(startModeFlag);
}
result.put(FIELD_START_MODE_FLAGS, startModeFlags);
}
return result;
}
@@ -18,6 +18,12 @@
android:title="@string/settings_general_manageareas_header"
android:summary="@string/empty" />
<com.sap.sailing.racecommittee.app.ui.fragments.preference.EditListPreference
android:key="what_a_key"
android:defaultValue="a,b,c"
android:title="@string/settings_general_manageareas_header"
android:summary="@string/empty" />
<EditTextPreference
android:key="@string/preference_mail_key"
android:defaultValue="@string/preference_mail_default"
@@ -37,6 +37,8 @@ public class AppPreferences {
private final static String PREFERENCE_BOAT_CLASS = "boatClassPref";
private final static String PREFERENCE_COURSE_LAYOUT = "courseLayoutPref";
private final static String PREFERENCE_NUMBER_OF_ROUNDS = "numberOfRoundsPref";
private final static String PREFERENCE_PROCEDURE_CONFIG_OVERWRITE = "procedureConfigOverwriteAllowed";
private final SharedPreferences preferences;
private final Context context;
@@ -230,4 +232,12 @@ public class AppPreferences {
return Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
}
public boolean isRacingProcedureConfigurationOverwriteAllowed() {
return preferences.getBoolean(PREFERENCE_PROCEDURE_CONFIG_OVERWRITE, true);
}
public void setRacingProcedureConfigurationOverwriteAllowed(boolean allowed) {
preferences.edit().putBoolean(PREFERENCE_PROCEDURE_CONFIG_OVERWRITE, allowed).commit();
}
}
@@ -6,6 +6,7 @@ import java.util.Date;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -63,6 +64,12 @@ public class RaceApplication extends Application {
defaultHandler.uncaughtException(thread, ex);
}
}
public static void restartApp(Context context) {
Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
}
}
@@ -8,8 +8,6 @@ import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
public interface DataStore {
@@ -40,7 +38,4 @@ public interface DataStore {
public CourseBase getLastPublishedCourseDesign();
public void setLastPublishedCourseDesign(CourseBase courseData);
public StoreableConfiguration<DeviceConfiguration> getTabletConfiguration();
public void setTabletConfiguration(StoreableConfiguration<DeviceConfiguration> configuration);
}
@@ -9,8 +9,6 @@ import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.impl.SharedDomainFactoryImpl;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.utils.CollectionUtils;
@@ -22,7 +20,6 @@ public enum InMemoryDataStore implements DataStore {
private HashMap<Serializable, ManagedRace> managedRaceById;
private HashMap<Serializable, Mark> marksById;
private CourseBase courseData;
private StoreableConfiguration<DeviceConfiguration> configuration;
private SharedDomainFactory domainFactory;
private InMemoryDataStore() {
@@ -35,7 +32,6 @@ public enum InMemoryDataStore implements DataStore {
this.managedRaceById = new HashMap<Serializable, ManagedRace>();
this.marksById = new HashMap<Serializable, Mark>();
this.courseData = null;
this.configuration = null;
this.domainFactory = new SharedDomainFactoryImpl();
}
@@ -177,14 +173,4 @@ public enum InMemoryDataStore implements DataStore {
public void setLastPublishedCourseDesign(CourseBase courseData) {
this.courseData = courseData;
}
@Override
public StoreableConfiguration<DeviceConfiguration> getTabletConfiguration() {
return configuration;
}
@Override
public void setTabletConfiguration(StoreableConfiguration<DeviceConfiguration> configuration) {
this.configuration = configuration;
}
}
@@ -21,7 +21,7 @@ import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationIdentifier;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.impl.BoatClassImpl;
import com.sap.sailing.domain.base.impl.CompetitorImpl;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
@@ -89,7 +89,7 @@ public class OfflineDataManager extends DataManager {
RaceLogEventFactory factory = new RaceLogEventFactoryImpl();
RaceLog log = new RaceLogImpl(UUID.randomUUID());
final RaceLogEventAuthor author = AppPreferences.on(context).getAuthor();
StoreableConfiguration<RacingProceduresConfiguration> configuration = new PreferencesBasedRacingProceduresConfiguration(preferences);
ConfigurationLoader<RacingProceduresConfiguration> configuration = new PreferencesBasedRacingProceduresConfiguration(preferences);
log.add(factory.createStartTimeEvent(new MillisecondsTimePoint(new Date().getTime() - 2000), author,
1, new MillisecondsTimePoint(new Date().getTime() - 1000)));
@@ -209,11 +209,11 @@ public class OfflineDataManager extends DataManager {
}
@Override
public LoaderCallbacks<DataLoaderResult<StoreableConfiguration<DeviceConfiguration>>> createConfigurationLoader(DeviceConfigurationIdentifier identifier,
LoadClient<StoreableConfiguration<DeviceConfiguration>> callback) {
return new ImmediateDataLoaderCallbacks<StoreableConfiguration<DeviceConfiguration>>(context, callback, new Callable<StoreableConfiguration<DeviceConfiguration>>() {
public LoaderCallbacks<DataLoaderResult<ConfigurationLoader<DeviceConfiguration>>> createConfigurationLoader(DeviceConfigurationIdentifier identifier,
LoadClient<ConfigurationLoader<DeviceConfiguration>> callback) {
return new ImmediateDataLoaderCallbacks<ConfigurationLoader<DeviceConfiguration>>(context, callback, new Callable<ConfigurationLoader<DeviceConfiguration>>() {
@Override
public StoreableConfiguration<DeviceConfiguration> call() throws Exception {
public ConfigurationLoader<DeviceConfiguration> call() throws Exception {
throw new IllegalStateException("No remote configuration in offline mode.");
}
});
@@ -21,17 +21,17 @@ import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationIdentifier;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.racelog.RaceLogServletConstants;
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
import com.sap.sailing.racecommittee.app.data.deserialization.impl.StoredDeviceConfigurationJsonDeserializer;
import com.sap.sailing.racecommittee.app.data.deserialization.impl.PreferencesBasedDeviceConfigurationJsonDeserializer;
import com.sap.sailing.racecommittee.app.data.handlers.CompetitorsDataHandler;
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.DeviceConfigurationDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.EventsDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.ManagedRacesDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.MarksDataHandler;
import com.sap.sailing.racecommittee.app.data.handlers.NullDataHandler;
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;
@@ -139,7 +139,7 @@ public class OnlineDataManager extends DataManager {
return new DataLoaderCallbacks<Collection<ManagedRace>>(callback, new LoaderCreator<Collection<ManagedRace>>() {
@Override
public Loader<DataLoaderResult<Collection<ManagedRace>>> create(int id, Bundle args) throws Exception {
StoreableConfiguration<RacingProceduresConfiguration> configuration =
ConfigurationLoader<RacingProceduresConfiguration> configuration =
new PreferencesBasedRacingProceduresConfiguration(preferences);
JsonDeserializer<BoatClass> boatClassDeserializer = new BoatClassJsonDeserializer(domainFactory);
@@ -236,18 +236,18 @@ public class OnlineDataManager extends DataManager {
}
@Override
public LoaderCallbacks<DataLoaderResult<StoreableConfiguration<DeviceConfiguration>>> createConfigurationLoader(final DeviceConfigurationIdentifier identifier,
LoadClient<StoreableConfiguration<DeviceConfiguration>> callback) {
return new DataLoaderCallbacks<StoreableConfiguration<DeviceConfiguration>>(callback, new LoaderCreator<StoreableConfiguration<DeviceConfiguration>>() {
public LoaderCallbacks<DataLoaderResult<ConfigurationLoader<DeviceConfiguration>>> createConfigurationLoader(final DeviceConfigurationIdentifier identifier,
LoadClient<ConfigurationLoader<DeviceConfiguration>> callback) {
return new DataLoaderCallbacks<ConfigurationLoader<DeviceConfiguration>>(callback, new LoaderCreator<ConfigurationLoader<DeviceConfiguration>>() {
@Override
public Loader<DataLoaderResult<StoreableConfiguration<DeviceConfiguration>>> create(int id, Bundle args) throws Exception {
public Loader<DataLoaderResult<ConfigurationLoader<DeviceConfiguration>>> create(int id, Bundle args) throws Exception {
ExLog.i(TAG, String.format("Creating Configuration-OnlineDataLoader %d", id));
DataHandler<StoreableConfiguration<DeviceConfiguration>> handler = new DeviceConfigurationDataHandler(OnlineDataManager.this);
DataParser<StoreableConfiguration<DeviceConfiguration>> parser = new DeviceConfigurationParser(
StoredDeviceConfigurationJsonDeserializer.create(preferences));
DataHandler<ConfigurationLoader<DeviceConfiguration>> handler = new NullDataHandler<ConfigurationLoader<DeviceConfiguration>>();
DataParser<ConfigurationLoader<DeviceConfiguration>> parser = new DeviceConfigurationParser(
PreferencesBasedDeviceConfigurationJsonDeserializer.create(preferences));
return new OnlineDataLoader<StoreableConfiguration<DeviceConfiguration>>(
return new OnlineDataLoader<ConfigurationLoader<DeviceConfiguration>>(
context,
new URL(preferences.getServerBaseURL() + "/sailingserver/rc/configuration?client="+ identifier.getClientIdentifier()),
parser, handler);
@@ -13,7 +13,7 @@ import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationIdentifier;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
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;
@@ -130,6 +130,6 @@ public interface ReadonlyDataManager {
* {@link LoaderManager#initLoader(int, android.os.Bundle, LoaderCallbacks)} or
* {@link LoaderManager#restartLoader(int, android.os.Bundle, LoaderCallbacks)}.
*/
public LoaderCallbacks<DataLoaderResult<StoreableConfiguration<DeviceConfiguration>>> createConfigurationLoader(DeviceConfigurationIdentifier identifier,
LoadClient<StoreableConfiguration<DeviceConfiguration>> callback);
public LoaderCallbacks<DataLoaderResult<ConfigurationLoader<DeviceConfiguration>>> createConfigurationLoader(DeviceConfigurationIdentifier identifier,
LoadClient<ConfigurationLoader<DeviceConfiguration>> callback);
}
@@ -2,9 +2,7 @@ package com.sap.sailing.racecommittee.app.data.deserialization.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.impl.DeviceConfigurationImpl;
import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.domain.configuration.impl.PreferencesBasedDeviceConfiguration;
@@ -12,17 +10,17 @@ import com.sap.sailing.racecommittee.app.domain.configuration.impl.PreferencesBa
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.DeviceConfigurationJsonDeserializer;
public class StoredDeviceConfigurationJsonDeserializer extends DeviceConfigurationJsonDeserializer {
public class PreferencesBasedDeviceConfigurationJsonDeserializer extends DeviceConfigurationJsonDeserializer {
public static StoredDeviceConfigurationJsonDeserializer create(final AppPreferences preferences) {
return new StoredDeviceConfigurationJsonDeserializer(preferences,
new StoredRacingProceduresConfigurationJsonDeserializer(preferences));
public static PreferencesBasedDeviceConfigurationJsonDeserializer create(final AppPreferences preferences) {
return new PreferencesBasedDeviceConfigurationJsonDeserializer(preferences,
new PreferencesBasedRacingProceduresConfigurationJsonDeserializer(preferences));
}
private final AppPreferences preferences;
public StoredDeviceConfigurationJsonDeserializer(AppPreferences preferences,
StoredRacingProceduresConfigurationJsonDeserializer proceduresDeserializer) {
public PreferencesBasedDeviceConfigurationJsonDeserializer(AppPreferences preferences,
PreferencesBasedRacingProceduresConfigurationJsonDeserializer proceduresDeserializer) {
super(proceduresDeserializer);
this.preferences = preferences;
}
@@ -33,9 +31,8 @@ public class StoredDeviceConfigurationJsonDeserializer extends DeviceConfigurati
(PreferencesBasedRacingProceduresConfiguration) proceduresConfiguration);
}
@SuppressWarnings("unchecked")
public StoreableConfiguration<DeviceConfiguration> deserializeAsStored(JSONObject object) throws JsonDeserializationException {
return (StoreableConfiguration<DeviceConfiguration>) super.deserialize(object);
public PreferencesBasedDeviceConfiguration deserializeAsStored(JSONObject object) throws JsonDeserializationException {
return (PreferencesBasedDeviceConfiguration) deserialize(object);
}
}
@@ -1,15 +1,18 @@
package com.sap.sailing.racecommittee.app.data.deserialization.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.configuration.impl.RacingProceduresConfigurationImpl;
import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.domain.configuration.impl.PreferencesBasedRacingProceduresConfiguration;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.RacingProceduresConfigurationJsonDeserializer;
public class StoredRacingProceduresConfigurationJsonDeserializer extends RacingProceduresConfigurationJsonDeserializer {
public class PreferencesBasedRacingProceduresConfigurationJsonDeserializer extends RacingProceduresConfigurationJsonDeserializer {
private final AppPreferences preferences;
public StoredRacingProceduresConfigurationJsonDeserializer(AppPreferences preferences) {
public PreferencesBasedRacingProceduresConfigurationJsonDeserializer(AppPreferences preferences) {
this.preferences = preferences;
}
@@ -17,4 +20,8 @@ public class StoredRacingProceduresConfigurationJsonDeserializer extends RacingP
protected RacingProceduresConfigurationImpl createConfiguration() {
return new PreferencesBasedRacingProceduresConfiguration(preferences);
}
public PreferencesBasedRacingProceduresConfiguration deserializeAsStored(JSONObject object) throws JsonDeserializationException {
return (PreferencesBasedRacingProceduresConfiguration) deserialize(object);
}
}
@@ -1,28 +0,0 @@
package com.sap.sailing.racecommittee.app.data.handlers;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.racecommittee.app.data.OnlineDataManager;
public class DeviceConfigurationDataHandler extends DataHandler<StoreableConfiguration<DeviceConfiguration>> {
public DeviceConfigurationDataHandler(OnlineDataManager manager) {
super(manager);
}
@Override
public boolean hasCachedResults() {
return manager.getDataStore().getTabletConfiguration() != null;
}
@Override
public StoreableConfiguration<DeviceConfiguration> getCachedResults() {
return manager.getDataStore().getTabletConfiguration();
}
@Override
public void onResult(StoreableConfiguration<DeviceConfiguration> data) {
manager.getDataStore().setTabletConfiguration(data);
}
}
@@ -6,20 +6,20 @@ import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.racecommittee.app.data.deserialization.impl.StoredDeviceConfigurationJsonDeserializer;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.racecommittee.app.data.deserialization.impl.PreferencesBasedDeviceConfigurationJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
public class DeviceConfigurationParser implements DataParser<StoreableConfiguration<DeviceConfiguration>> {
public class DeviceConfigurationParser implements DataParser<ConfigurationLoader<DeviceConfiguration>> {
private StoredDeviceConfigurationJsonDeserializer deserializer;
private PreferencesBasedDeviceConfigurationJsonDeserializer deserializer;
public DeviceConfigurationParser(StoredDeviceConfigurationJsonDeserializer deserializer) {
public DeviceConfigurationParser(PreferencesBasedDeviceConfigurationJsonDeserializer deserializer) {
this.deserializer = deserializer;
}
@Override
public StoreableConfiguration<DeviceConfiguration> parse(Reader reader) throws Exception {
public ConfigurationLoader<DeviceConfiguration> parse(Reader reader) throws Exception {
Object parsedResult = JSONValue.parseWithException(reader);
JSONObject jsonObject = Helpers.toJSONObjectSafe(parsedResult);
return deserializer.deserializeAsStored(jsonObject);
@@ -10,8 +10,8 @@ import org.json.simple.JSONValue;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.racegroup.RaceCell;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.base.racegroup.RaceRow;
@@ -34,13 +34,13 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
// private static final String TAG = ManagedRacesDataParser.class.getName();
private final JsonDeserializer<RaceGroup> deserializer;
private final StoreableConfiguration<RacingProceduresConfiguration> configuration;
private final ConfigurationLoader<RacingProceduresConfiguration> globalConfiguration;
private final RaceLogEventAuthor author;
public ManagedRacesDataParser(RaceLogEventAuthor author, StoreableConfiguration<RacingProceduresConfiguration> configuration,
public ManagedRacesDataParser(RaceLogEventAuthor author, ConfigurationLoader<RacingProceduresConfiguration> configuration,
JsonDeserializer<RaceGroup> deserializer) {
this.author = author;
this.configuration = configuration;
this.globalConfiguration = configuration;
this.deserializer = deserializer;
}
@@ -53,6 +53,9 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
JSONObject json = Helpers.toJSONObjectSafe(element);
RaceGroup group = deserializer.deserialize(json);
// TODO: store configuration of RaceGroup!
globalConfiguration.store();
addManagedRaces(managedRaces, group);
}
@@ -76,7 +79,7 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
RacingProcedureType startType = raceGroup.getDefaultRacingProcedureType();
FleetIdentifier fleetIdentifier = new FleetIdentifierImpl(fleet, series, raceGroup);
ManagedRaceIdentifier identifier = new ManagedRaceIdentifierImpl(name, fleetIdentifier);
RaceState state = RaceStateImpl.create(raceLog, author, startType, configuration);
RaceState state = RaceStateImpl.create(raceLog, author, startType, globalConfiguration);
return new ManagedRaceImpl(identifier, state);
}
@@ -2,29 +2,31 @@ package com.sap.sailing.racecommittee.app.domain.configuration.impl;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.configuration.impl.DeviceConfigurationImpl;
import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.logging.ExLog;
public class PreferencesBasedDeviceConfiguration extends DeviceConfigurationImpl implements StoreableConfiguration<DeviceConfiguration> {
public class PreferencesBasedDeviceConfiguration extends DeviceConfigurationImpl implements ConfigurationLoader<DeviceConfiguration> {
private static final long serialVersionUID = 9146162601389924219L;
private static final String TAG = PreferencesBasedDeviceConfiguration.class.getName();
private final AppPreferences preferences;
private final StoreableConfiguration<RacingProceduresConfiguration> storableRacingProceduresConfiguration;
private final ConfigurationLoader<RacingProceduresConfiguration> storableRacingProceduresConfiguration;
public PreferencesBasedDeviceConfiguration(final AppPreferences preferences,
StoreableConfiguration<RacingProceduresConfiguration> proceduresConfiguration) {
super(proceduresConfiguration.load());
ConfigurationLoader<RacingProceduresConfiguration> proceduresConfiguration) {
super(proceduresConfiguration == null ? null : proceduresConfiguration.load());
this.preferences = preferences;
this.storableRacingProceduresConfiguration = proceduresConfiguration;
}
@Override
public DeviceConfiguration load() {
setRacingProceduresConfiguration(storableRacingProceduresConfiguration.load());
if (storableRacingProceduresConfiguration != null) {
setRacingProceduresConfiguration(storableRacingProceduresConfiguration.load());
}
setAllowedCourseAreaNames(preferences.getManagedCourseAreaNames());
setResultsMailRecipient(preferences.getMailRecipient());
@@ -36,12 +38,19 @@ public class PreferencesBasedDeviceConfiguration extends DeviceConfigurationImpl
setDefaultCourseDesignerMode(preferences.getDefaultCourseDesignerMode());
}
setByNameDesignerCourseNames(preferences.getByNameCourseDesignerCourseNames());
return super.copy(this);
return copy();
}
@Override
public void store() {
storableRacingProceduresConfiguration.store();
ExLog.i(TAG, "Storing new device configuration.");
if (storableRacingProceduresConfiguration != null) {
storableRacingProceduresConfiguration.store();
preferences.setRacingProcedureConfigurationOverwriteAllowed(false);
} else {
preferences.setRacingProcedureConfigurationOverwriteAllowed(true);
}
if (getAllowedCourseAreaNames() != null) {
preferences.setManagedCourseAreaNames(getAllowedCourseAreaNames());
@@ -1,16 +1,17 @@
package com.sap.sailing.racecommittee.app.domain.configuration.impl;
import com.sap.sailing.domain.base.configuration.RacingProceduresConfiguration;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.configuration.impl.RacingProceduresConfigurationImpl;
import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.logging.ExLog;
public class PreferencesBasedRacingProceduresConfiguration extends RacingProceduresConfigurationImpl implements
StoreableConfiguration<RacingProceduresConfiguration> {
ConfigurationLoader<RacingProceduresConfiguration> {
private static final long serialVersionUID = -2109422929668306199L;
private static final String TAG = PreferencesBasedRacingProceduresConfiguration.class.getName();
@SuppressWarnings("unused")
private final AppPreferences preferences;
public PreferencesBasedRacingProceduresConfiguration(final AppPreferences preferences) {
@@ -19,11 +20,34 @@ public class PreferencesBasedRacingProceduresConfiguration extends RacingProcedu
@Override
public RacingProceduresConfiguration load() {
return super.copy(this);
// TODO: implement loading of RPC
setClassFlag(null);
setHasInidividualRecall(null);
setStartModeFlags(null);
return copy();
}
@Override
public void store() {
if (!preferences.isRacingProcedureConfigurationOverwriteAllowed()) {
ExLog.i(TAG, "Overwrite of procedure configuration not allowed.");
return;
}
ExLog.i(TAG, "Storing new racing procedure configuration.");
// TODO: implement storing of RPC
if (getClassFlag() != null) {
}
if (hasInidividualRecall() != null) {
}
if (getStartModeFlags() != null) {
}
}
@@ -15,7 +15,7 @@ import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationIdentifier;
import com.sap.sailing.domain.base.configuration.StoreableConfiguration;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.configuration.impl.DeviceConfigurationIdentifierImpl;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.AppPreferences;
@@ -112,14 +112,17 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
DeviceConfigurationIdentifier identifier = new DeviceConfigurationIdentifierImpl(
AppPreferences.on(getApplicationContext()).getAndroidIdentifier());
getLoaderManager().restartLoader(0, null,
dataManager.createConfigurationLoader(identifier, new LoadClient<StoreableConfiguration<DeviceConfiguration>>() {
dataManager.createConfigurationLoader(identifier, new LoadClient<ConfigurationLoader<DeviceConfiguration>>() {
@Override
public void onLoadSucceded(StoreableConfiguration<DeviceConfiguration> configuration, boolean isCached) {
public void onLoadSucceded(ConfigurationLoader<DeviceConfiguration> configuration, boolean isCached) {
setProgressBarIndeterminateVisibility(false);
progressDialog.dismiss();
// this is our 'global' configuration, so let's enable overwrite for everything!
preferences.setRacingProcedureConfigurationOverwriteAllowed(true);
configuration.store();
Toast.makeText(getApplicationContext(), getString(R.string.loading_configuration_succeded), Toast.LENGTH_LONG).show();
showCourseAreaListFragment(eventId);
}
@@ -1,8 +1,11 @@
package com.sap.sailing.racecommittee.app.ui.fragments.preference;
import com.sap.sailing.racecommittee.app.utils.MultiplePreferenceChangeListener;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
@@ -32,7 +35,7 @@ public class BasePreferenceFragment extends PreferenceFragment {
};
protected static void bindPreferenceSummaryToValue(Preference preference) {
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
addOnPreferenceChangeListener(preference, sBindPreferenceSummaryToValueListener);
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
@@ -41,7 +44,7 @@ public class BasePreferenceFragment extends PreferenceFragment {
}
protected static void bindPreferenceSummaryToInteger(Preference preference) {
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
addOnPreferenceChangeListener(preference, sBindPreferenceSummaryToValueListener);
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
@@ -51,7 +54,7 @@ public class BasePreferenceFragment extends PreferenceFragment {
protected static void bindPreferenceToCheckbox(CheckBoxPreference checkboxPreference, final Preference target) {
target.setEnabled(checkboxPreference.isChecked());
checkboxPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
addOnPreferenceChangeListener(checkboxPreference, new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
target.setEnabled((Boolean) value);
@@ -59,4 +62,21 @@ public class BasePreferenceFragment extends PreferenceFragment {
}
});
}
protected static void addOnPreferenceChangeListener(Preference preference, OnPreferenceChangeListener newListener) {
OnPreferenceChangeListener oldListener = preference.getOnPreferenceChangeListener();
if (oldListener == null) {
MultiplePreferenceChangeListener multiListener = new MultiplePreferenceChangeListener();
multiListener.addOnPreferenceChangeListener(newListener);
preference.setOnPreferenceChangeListener(multiListener);
} else if (oldListener instanceof MultiplePreferenceChangeListener) {
MultiplePreferenceChangeListener multiListener = (MultiplePreferenceChangeListener) oldListener;
multiListener.addOnPreferenceChangeListener(newListener);
} else {
MultiplePreferenceChangeListener multiListener = new MultiplePreferenceChangeListener();
multiListener.addOnPreferenceChangeListener(oldListener);
multiListener.addOnPreferenceChangeListener(newListener);
preference.setOnPreferenceChangeListener(multiListener);
}
}
}
@@ -0,0 +1,97 @@
package com.sap.sailing.racecommittee.app.ui.fragments.preference;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.logging.ExLog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.preference.DialogPreference;
import android.util.AttributeSet;
public class EditListPreference extends DialogPreference {
private static final String TAG = EditListPreference.class.getName();
private static final Set<String> defaultFallbackValue = new HashSet<String>();
private Set<String> currentValue;
public EditListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.race_choose_line_opening_time_view);
}
@SuppressWarnings("unchecked")
@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
if (restorePersistedValue) {
// Restore existing state
currentValue = getPersistedStringSet(defaultFallbackValue);
} else {
// Set default state from the XML attribute
currentValue = (Set<String>) defaultValue;
persistStringSet(currentValue);
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return toSet(a.getString(index));
}
protected static Set<String> toSet(String csl) {
if (csl == null || csl.isEmpty()) {
return new HashSet<String>();
}
String[] values = csl.split(",");
for (int i = 0; i < values.length; i++) {
values[i] = values[i].trim();
}
return new HashSet<String>(Arrays.asList(values));
}
@Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
ExLog.i(TAG, "Storing result...");
persistStringSet(currentValue);
}
}
private boolean persistStringSet(Set<String> value) {
if (shouldPersist()) {
// Shouldn't store null
if (value == getPersistedStringSet(null)) {
// It's already there, so the same as persisting
return true;
}
SharedPreferences.Editor editor = getEditor();
editor.putStringSet(getKey(), value);
if (shouldCommit()) {
editor.commit();
}
return true;
}
return false;
}
protected Set<String> getPersistedStringSet(Set<String> defaultReturnValue) {
if (!shouldPersist()) {
return defaultReturnValue;
}
return getSharedPreferences().getStringSet(getKey(), defaultReturnValue);
}
}
@@ -24,8 +24,7 @@ public class GeneralPreferenceFragment extends BasePreferenceFragment {
private void setupServerUrlBox() {
Preference preference = findPreference(getString(R.string.preference_server_url_key));
preference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
addOnPreferenceChangeListener(preference, new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Toast.makeText(getActivity(),
@@ -36,13 +35,14 @@ public class GeneralPreferenceFragment extends BasePreferenceFragment {
}
private void setupLanguageButton() {
Preference button = findPreference(getString(R.string.preference_language_key));
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
Preference preference = findPreference(getString(R.string.preference_language_key));
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.android.settings", "com.android.settings.LanguageSettings");
startActivity(intent);
preference.getOnPreferenceChangeListener().onPreferenceChange(preference, null);
return true;
}
});
@@ -0,0 +1,37 @@
package com.sap.sailing.racecommittee.app.utils;
import java.util.HashSet;
import java.util.Set;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
public class MultiplePreferenceChangeListener implements OnPreferenceChangeListener {
private final Set<OnPreferenceChangeListener> listeners;
public MultiplePreferenceChangeListener() {
this.listeners = new HashSet<Preference.OnPreferenceChangeListener>();
}
public void addOnPreferenceChangeListener(OnPreferenceChangeListener listener) {
listeners.add(listener);
}
public void removeOnPreferenceChangeListener(OnPreferenceChangeListener listener) {
listeners.remove(listener);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean result = true;
for (OnPreferenceChangeListener listener : listeners) {
if (!listener.onPreferenceChange(preference, newValue)) {
result = false;
}
}
return result;
}
}