From e0f2309b16937c9031968a3af96d5028efa563f5 Mon Sep 17 00:00:00 2001 From: Lukas Niemeier Date: Fri, 22 Nov 2013 01:27:26 +0100 Subject: [PATCH] # working towards implementing the RacingProcedureConfiguration --- .../racelog/state/test/RaceStateTest.java | 6 +- .../configuration/ConfigurationLoader.java | 20 ++++ .../RacingProcedureConfiguration.java | 16 +++ .../configuration/StoreableConfiguration.java | 20 ---- .../impl/DeviceConfigurationImpl.java | 8 +- ...> EmptyRacingProceduresConfiguration.java} | 10 +- .../RacingProceduresConfigurationImpl.java | 48 ++++++++- .../procedures/ESSConfiguration.java | 4 +- .../procedures/GateStartConfiguration.java | 4 +- .../procedures/RRS26Configuration.java | 9 +- .../impl/RRS26StartModeFlagFinder.java | 11 ++- .../racelog/state/impl/RaceStateImpl.java | 10 +- .../state/impl/ReadonlyRaceStateImpl.java | 4 +- .../ReadonlyRacingProcedure.java | 2 + .../ess/impl/ESSRacingProcedureImpl.java | 17 ++-- .../impl/GateStartRacingProcedureImpl.java | 9 +- .../impl/BaseRacingProcedure.java | 19 +++- .../impl/RacingProcedureFactoryImpl.java | 4 +- .../impl/ReadonlyRacingProcedureFactory.java | 6 +- .../rrs26/impl/RRS26RacingProcedureImpl.java | 23 +++-- .../DeviceConfigurationJsonDeserializer.java | 8 +- ...oceduresConfigurationJsonDeserializer.java | 27 ++++++ .../racegroup/impl/RaceGroupDeserializer.java | 1 + ...ProceduresConfigurationJsonSerializer.java | 20 ++++ .../res/xml/preference_general.xml | 6 ++ .../racecommittee/app/AppPreferences.java | 10 ++ .../racecommittee/app/RaceApplication.java | 7 ++ .../racecommittee/app/data/DataStore.java | 5 - .../app/data/InMemoryDataStore.java | 14 --- .../app/data/OfflineDataManager.java | 12 +-- .../app/data/OnlineDataManager.java | 24 ++--- .../app/data/ReadonlyDataManager.java | 6 +- ...dDeviceConfigurationJsonDeserializer.java} | 19 ++-- ...ceduresConfigurationJsonDeserializer.java} | 11 ++- .../DeviceConfigurationDataHandler.java | 28 ------ .../parsers/DeviceConfigurationParser.java | 12 +-- .../data/parsers/ManagedRacesDataParser.java | 13 ++- .../PreferencesBasedDeviceConfiguration.java | 25 +++-- ...cesBasedRacingProceduresConfiguration.java | 32 +++++- .../app/ui/activities/LoginActivity.java | 9 +- .../preference/BasePreferenceFragment.java | 26 ++++- .../preference/EditListPreference.java | 97 +++++++++++++++++++ .../preference/GeneralPreferenceFragment.java | 8 +- .../MultiplePreferenceChangeListener.java | 37 +++++++ 44 files changed, 524 insertions(+), 183 deletions(-) create mode 100644 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/ConfigurationLoader.java create mode 100644 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RacingProcedureConfiguration.java delete mode 100644 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/StoreableConfiguration.java rename java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/{EmptyConfiguration.java => EmptyRacingProceduresConfiguration.java} (53%) rename mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/{StoredDeviceConfigurationJsonDeserializer.java => PreferencesBasedDeviceConfigurationJsonDeserializer.java} (55%) rename mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/{StoredRacingProceduresConfigurationJsonDeserializer.java => PreferencesBasedRacingProceduresConfigurationJsonDeserializer.java} (55%) delete mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/DeviceConfigurationDataHandler.java create mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/EditListPreference.java create mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/MultiplePreferenceChangeListener.java diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java index d11a1dce380..79e64ab2c13 100644 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/state/test/RaceStateTest.java @@ -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 configuration; + private ConfigurationLoader 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); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/ConfigurationLoader.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/ConfigurationLoader.java new file mode 100644 index 00000000000..97c25bff289 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/ConfigurationLoader.java @@ -0,0 +1,20 @@ +package com.sap.sailing.domain.base.configuration; + + +/** + * Capable of loading and storing a {@link ConfigurationType}. + */ +public interface ConfigurationLoader { + + /** + * 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(); +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RacingProcedureConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RacingProcedureConfiguration.java new file mode 100644 index 00000000000..cce9e275ade --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/RacingProcedureConfiguration.java @@ -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(); + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/StoreableConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/StoreableConfiguration.java deleted file mode 100644 index 2abe630c4e9..00000000000 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/StoreableConfiguration.java +++ /dev/null @@ -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 { - - /** - * Reloads the configuration. - * @return A copy of this {@link ConfigurationType} after loading. - */ - ConfigurationType load(); - - - /** - * Saves the configuration - */ - void store(); -} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/DeviceConfigurationImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/DeviceConfigurationImpl.java index 4d230e17e68..c39b2883b1a 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/DeviceConfigurationImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/DeviceConfigurationImpl.java @@ -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; } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyRacingProceduresConfiguration.java similarity index 53% rename from java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyConfiguration.java rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyRacingProceduresConfiguration.java index 61a85310f9d..d869fe4d3e5 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyConfiguration.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/EmptyRacingProceduresConfiguration.java @@ -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 { +public class EmptyRacingProceduresConfiguration extends RacingProceduresConfigurationImpl implements + ConfigurationLoader { private static final long serialVersionUID = -4187341706420504456L; @Override public RacingProceduresConfiguration load() { - return super.copy(this); + return copy(); } @Override diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RacingProceduresConfigurationImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RacingProceduresConfigurationImpl.java index 5e559e4c473..29840923527 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RacingProceduresConfigurationImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/impl/RacingProceduresConfigurationImpl.java @@ -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 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 getStartModeFlags() { + return startModeFlags; + } + + public void setStartModeFlags(List flags) { + this.startModeFlags = flags; + } + + protected RacingProceduresConfiguration copy() { + RacingProceduresConfigurationImpl copy = new RacingProceduresConfigurationImpl(); + copy.setClassFlag(classFlag); + copy.setHasInidividualRecall(hasInidividualRecall); + copy.setStartModeFlags(startModeFlags); + return copy; } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/ESSConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/ESSConfiguration.java index 3a65ca1bc06..a07ea9ff4e6 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/ESSConfiguration.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/ESSConfiguration.java @@ -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 { } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/GateStartConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/GateStartConfiguration.java index f70d48a223b..0caea483ca1 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/GateStartConfiguration.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/GateStartConfiguration.java @@ -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 { } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/RRS26Configuration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/RRS26Configuration.java index 69b84eb700e..83c56adfe2a 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/RRS26Configuration.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/configuration/procedures/RRS26Configuration.java @@ -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 getStartModeFlags(); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RRS26StartModeFlagFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RRS26StartModeFlagFinder.java index c554fd45e58..f9b0d0d4aa6 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RRS26StartModeFlagFinder.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RRS26StartModeFlagFinder.java @@ -11,8 +11,10 @@ import com.sap.sailing.domain.racelog.RaceLogFlagEvent; public class RRS26StartModeFlagFinder extends RaceLogAnalyzer { - private final List startModeFlags = Arrays.asList(Flags.PAPA, Flags.ZULU, Flags.BLACK, Flags.INDIA); - private RacingProcedureTypeAnalyzer procedureAnalyzer; + private final static List defaultStartModeFlags = Arrays.asList(Flags.PAPA, Flags.ZULU, Flags.BLACK, Flags.INDIA); + + private final RacingProcedureTypeAnalyzer procedureAnalyzer; + private final List startModeFlags; /** * Searches for the start mode flag of a RRS26 race. @@ -22,11 +24,16 @@ public class RRS26StartModeFlagFinder extends RaceLogAnalyzer { * {@link IllegalArgumentException} is thrown. */ public RRS26StartModeFlagFinder(RacingProcedureTypeAnalyzer procedureAnalyzer, RaceLog raceLog) { + this(procedureAnalyzer, raceLog, defaultStartModeFlags); + } + + public RRS26StartModeFlagFinder(RacingProcedureTypeAnalyzer procedureAnalyzer, RaceLog raceLog, List 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 diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/RaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/RaceStateImpl.java index 8855c21f15d..b233622c60f 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/RaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/RaceStateImpl.java @@ -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 configuration) { + public static RaceState create(RaceLog raceLog, RaceLogEventAuthor author, ConfigurationLoader 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 configuration) { + ConfigurationLoader configuration) { return new RaceStateImpl(raceLog, author, RaceLogEventFactory.INSTANCE, initalRacingProcedureType, diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/ReadonlyRaceStateImpl.java index 618f88239f3..c13acb998de 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/impl/ReadonlyRaceStateImpl.java @@ -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; diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ReadonlyRacingProcedure.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ReadonlyRacingProcedure.java index 31b2e056f8c..0b28f06e343 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ReadonlyRacingProcedure.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ReadonlyRacingProcedure.java @@ -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); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java index 8cae208f82c..65ea701a6cd 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/ess/impl/ESSRacingProcedureImpl.java @@ -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(); + } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java index 0ebf9b9d953..02199828032 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/gate/impl/GateStartRacingProcedureImpl.java @@ -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); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/BaseRacingProcedure.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/BaseRacingProcedure.java index 7aa6e70b00a..4dbf21dd9b6 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/BaseRacingProcedure.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/BaseRacingProcedure.java @@ -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 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 createStartStateEvents(TimePoint startTime); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/RacingProcedureFactoryImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/RacingProcedureFactoryImpl.java index 941ba8887a0..cdfc4e693aa 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/RacingProcedureFactoryImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/RacingProcedureFactoryImpl.java @@ -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 configuration) { + ConfigurationLoader configuration) { super(configuration); this.author = author; this.factory = factory; diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java index 869d8d45e72..438097c53d6 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/impl/ReadonlyRacingProcedureFactory.java @@ -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 configuration; + protected final ConfigurationLoader configuration; - public ReadonlyRacingProcedureFactory(StoreableConfiguration configuration) { + public ReadonlyRacingProcedureFactory(ConfigurationLoader configuration) { this.configuration = configuration; } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/rrs26/impl/RRS26RacingProcedureImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/rrs26/impl/RRS26RacingProcedureImpl.java index 0893bc3a279..74d5f811cc5 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/rrs26/impl/RRS26RacingProcedureImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/state/racingprocedure/rrs26/impl/RRS26RacingProcedureImpl.java @@ -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(); + } } diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/DeviceConfigurationJsonDeserializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/DeviceConfigurationJsonDeserializer.java index 8012787ebca..08d787f780f 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/DeviceConfigurationJsonDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/DeviceConfigurationJsonDeserializer.java @@ -30,9 +30,13 @@ public class DeviceConfigurationJsonDeserializer implements JsonDeserializer { @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 result = new ArrayList(); + 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; } diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/racegroup/impl/RaceGroupDeserializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/racegroup/impl/RaceGroupDeserializer.java index 884c663494c..03ce9c8f8c6 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/racegroup/impl/RaceGroupDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/racegroup/impl/RaceGroupDeserializer.java @@ -38,6 +38,7 @@ public class RaceGroupDeserializer implements JsonDeserializer { if (object.containsKey(RaceGroupJsonSerializer.FIELD_COURSE_AREA)) { // TODO: deserialize CourseArea ... + // WHY should I? } if (object.containsKey(RaceGroupJsonSerializer.FIELD_BOAT_CLASS)) { diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RacingProceduresConfigurationJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RacingProceduresConfigurationJsonSerializer.java index 24e60ffcf72..967a0284c56 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RacingProceduresConfigurationJsonSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RacingProceduresConfigurationJsonSerializer.java @@ -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 { + 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; } diff --git a/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml b/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml index f82b53075fb..b113d9ee2ce 100644 --- a/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml +++ b/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml @@ -18,6 +18,12 @@ android:title="@string/settings_general_manageareas_header" android:summary="@string/empty" /> + + getTabletConfiguration(); - public void setTabletConfiguration(StoreableConfiguration configuration); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java index cffaa09bcf8..3ac61290d07 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java @@ -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 managedRaceById; private HashMap marksById; private CourseBase courseData; - private StoreableConfiguration configuration; private SharedDomainFactory domainFactory; private InMemoryDataStore() { @@ -35,7 +32,6 @@ public enum InMemoryDataStore implements DataStore { this.managedRaceById = new HashMap(); this.marksById = new HashMap(); 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 getTabletConfiguration() { - return configuration; - } - - @Override - public void setTabletConfiguration(StoreableConfiguration configuration) { - this.configuration = configuration; - } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java index 6dcd92b75f0..77b7b8a6d4f 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OfflineDataManager.java @@ -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 configuration = new PreferencesBasedRacingProceduresConfiguration(preferences); + ConfigurationLoader 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>> createConfigurationLoader(DeviceConfigurationIdentifier identifier, - LoadClient> callback) { - return new ImmediateDataLoaderCallbacks>(context, callback, new Callable>() { + public LoaderCallbacks>> createConfigurationLoader(DeviceConfigurationIdentifier identifier, + LoadClient> callback) { + return new ImmediateDataLoaderCallbacks>(context, callback, new Callable>() { @Override - public StoreableConfiguration call() throws Exception { + public ConfigurationLoader call() throws Exception { throw new IllegalStateException("No remote configuration in offline mode."); } }); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java index 01a065f540c..55376bed75e 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java @@ -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>(callback, new LoaderCreator>() { @Override public Loader>> create(int id, Bundle args) throws Exception { - StoreableConfiguration configuration = + ConfigurationLoader configuration = new PreferencesBasedRacingProceduresConfiguration(preferences); JsonDeserializer boatClassDeserializer = new BoatClassJsonDeserializer(domainFactory); @@ -236,18 +236,18 @@ public class OnlineDataManager extends DataManager { } @Override - public LoaderCallbacks>> createConfigurationLoader(final DeviceConfigurationIdentifier identifier, - LoadClient> callback) { - return new DataLoaderCallbacks>(callback, new LoaderCreator>() { + public LoaderCallbacks>> createConfigurationLoader(final DeviceConfigurationIdentifier identifier, + LoadClient> callback) { + return new DataLoaderCallbacks>(callback, new LoaderCreator>() { @Override - public Loader>> create(int id, Bundle args) throws Exception { + public Loader>> create(int id, Bundle args) throws Exception { ExLog.i(TAG, String.format("Creating Configuration-OnlineDataLoader %d", id)); - DataHandler> handler = new DeviceConfigurationDataHandler(OnlineDataManager.this); - DataParser> parser = new DeviceConfigurationParser( - StoredDeviceConfigurationJsonDeserializer.create(preferences)); + DataHandler> handler = new NullDataHandler>(); + DataParser> parser = new DeviceConfigurationParser( + PreferencesBasedDeviceConfigurationJsonDeserializer.create(preferences)); - return new OnlineDataLoader>( + return new OnlineDataLoader>( context, new URL(preferences.getServerBaseURL() + "/sailingserver/rc/configuration?client="+ identifier.getClientIdentifier()), parser, handler); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java index 34dc13cd05b..d81e88fba1e 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/ReadonlyDataManager.java @@ -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>> createConfigurationLoader(DeviceConfigurationIdentifier identifier, - LoadClient> callback); + public LoaderCallbacks>> createConfigurationLoader(DeviceConfigurationIdentifier identifier, + LoadClient> callback); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/StoredDeviceConfigurationJsonDeserializer.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/PreferencesBasedDeviceConfigurationJsonDeserializer.java similarity index 55% rename from mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/StoredDeviceConfigurationJsonDeserializer.java rename to mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/PreferencesBasedDeviceConfigurationJsonDeserializer.java index 6ed10693e46..58b4a7a9d62 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/StoredDeviceConfigurationJsonDeserializer.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/PreferencesBasedDeviceConfigurationJsonDeserializer.java @@ -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 deserializeAsStored(JSONObject object) throws JsonDeserializationException { - return (StoreableConfiguration) super.deserialize(object); + public PreferencesBasedDeviceConfiguration deserializeAsStored(JSONObject object) throws JsonDeserializationException { + return (PreferencesBasedDeviceConfiguration) deserialize(object); } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/StoredRacingProceduresConfigurationJsonDeserializer.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/PreferencesBasedRacingProceduresConfigurationJsonDeserializer.java similarity index 55% rename from mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/StoredRacingProceduresConfigurationJsonDeserializer.java rename to mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/PreferencesBasedRacingProceduresConfigurationJsonDeserializer.java index 76f41d25773..08008967ceb 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/StoredRacingProceduresConfigurationJsonDeserializer.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/deserialization/impl/PreferencesBasedRacingProceduresConfigurationJsonDeserializer.java @@ -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); + } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/DeviceConfigurationDataHandler.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/DeviceConfigurationDataHandler.java deleted file mode 100644 index 733959c6ebe..00000000000 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/DeviceConfigurationDataHandler.java +++ /dev/null @@ -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> { - - public DeviceConfigurationDataHandler(OnlineDataManager manager) { - super(manager); - } - - @Override - public boolean hasCachedResults() { - return manager.getDataStore().getTabletConfiguration() != null; - } - - @Override - public StoreableConfiguration getCachedResults() { - return manager.getDataStore().getTabletConfiguration(); - } - - @Override - public void onResult(StoreableConfiguration data) { - manager.getDataStore().setTabletConfiguration(data); - } - -} diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/DeviceConfigurationParser.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/DeviceConfigurationParser.java index 7296f4c0af8..cdf7e581705 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/DeviceConfigurationParser.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/DeviceConfigurationParser.java @@ -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> { +public class DeviceConfigurationParser implements DataParser> { - private StoredDeviceConfigurationJsonDeserializer deserializer; + private PreferencesBasedDeviceConfigurationJsonDeserializer deserializer; - public DeviceConfigurationParser(StoredDeviceConfigurationJsonDeserializer deserializer) { + public DeviceConfigurationParser(PreferencesBasedDeviceConfigurationJsonDeserializer deserializer) { this.deserializer = deserializer; } @Override - public StoreableConfiguration parse(Reader reader) throws Exception { + public ConfigurationLoader parse(Reader reader) throws Exception { Object parsedResult = JSONValue.parseWithException(reader); JSONObject jsonObject = Helpers.toJSONObjectSafe(parsedResult); return deserializer.deserializeAsStored(jsonObject); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java index 799605133a6..76d084f256f 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/parsers/ManagedRacesDataParser.java @@ -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 deserializer; - private final StoreableConfiguration configuration; + private final ConfigurationLoader globalConfiguration; private final RaceLogEventAuthor author; - public ManagedRacesDataParser(RaceLogEventAuthor author, StoreableConfiguration configuration, + public ManagedRacesDataParser(RaceLogEventAuthor author, ConfigurationLoader configuration, JsonDeserializer deserializer) { this.author = author; - this.configuration = configuration; + this.globalConfiguration = configuration; this.deserializer = deserializer; } @@ -53,6 +53,9 @@ public class ManagedRacesDataParser implements DataParser { +public class PreferencesBasedDeviceConfiguration extends DeviceConfigurationImpl implements ConfigurationLoader { private static final long serialVersionUID = 9146162601389924219L; private static final String TAG = PreferencesBasedDeviceConfiguration.class.getName(); private final AppPreferences preferences; - private final StoreableConfiguration storableRacingProceduresConfiguration; + private final ConfigurationLoader storableRacingProceduresConfiguration; public PreferencesBasedDeviceConfiguration(final AppPreferences preferences, - StoreableConfiguration proceduresConfiguration) { - super(proceduresConfiguration.load()); + ConfigurationLoader 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()); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/configuration/impl/PreferencesBasedRacingProceduresConfiguration.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/configuration/impl/PreferencesBasedRacingProceduresConfiguration.java index 9da98ed8489..74a77777fd8 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/configuration/impl/PreferencesBasedRacingProceduresConfiguration.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/configuration/impl/PreferencesBasedRacingProceduresConfiguration.java @@ -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 { + ConfigurationLoader { 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) { + + } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java index 0d2e8d1f539..294931c5a2a 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java @@ -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>() { + dataManager.createConfigurationLoader(identifier, new LoadClient>() { @Override - public void onLoadSucceded(StoreableConfiguration configuration, boolean isCached) { + public void onLoadSucceded(ConfigurationLoader 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); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/BasePreferenceFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/BasePreferenceFragment.java index 78ab650370f..39f93ca4f41 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/BasePreferenceFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/BasePreferenceFragment.java @@ -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); + } + } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/EditListPreference.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/EditListPreference.java new file mode 100644 index 00000000000..4eba95b76b9 --- /dev/null +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/EditListPreference.java @@ -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 defaultFallbackValue = new HashSet(); + private Set 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) defaultValue; + persistStringSet(currentValue); + } + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return toSet(a.getString(index)); + } + + protected static Set toSet(String csl) { + if (csl == null || csl.isEmpty()) { + return new HashSet(); + } + + String[] values = csl.split(","); + for (int i = 0; i < values.length; i++) { + values[i] = values[i].trim(); + } + + return new HashSet(Arrays.asList(values)); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + if (positiveResult) { + ExLog.i(TAG, "Storing result..."); + persistStringSet(currentValue); + } + } + + private boolean persistStringSet(Set 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 getPersistedStringSet(Set defaultReturnValue) { + if (!shouldPersist()) { + return defaultReturnValue; + } + + return getSharedPreferences().getStringSet(getKey(), defaultReturnValue); + } + + +} diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java index c375785ffd2..f2033e924f9 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java @@ -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; } }); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/MultiplePreferenceChangeListener.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/MultiplePreferenceChangeListener.java new file mode 100644 index 00000000000..ac8bc1eab48 --- /dev/null +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/MultiplePreferenceChangeListener.java @@ -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 listeners; + + public MultiplePreferenceChangeListener() { + this.listeners = new HashSet(); + } + + 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; + } + +}