Loading k9mail/src/main/java/com/fsck/k9/preferences/Settings.java +52 −44 Original line number Original line Diff line number Diff line Loading @@ -99,7 +99,7 @@ public class Settings { * * * @param version * @param version * The content version of the settings in {@code validatedSettingsMutable}. * The content version of the settings in {@code validatedSettingsMutable}. * @param upgraders * @param customUpgraders * A map of {@link SettingsUpgrader}s for nontrivial settings upgrades. * A map of {@link SettingsUpgrader}s for nontrivial settings upgrades. * @param settings * @param settings * The structure describing the different settings, possibly containing multiple * The structure describing the different settings, possibly containing multiple Loading @@ -111,63 +111,72 @@ public class Settings { * @return A set of setting names that were removed during the upgrade process or {@code null} * @return A set of setting names that were removed during the upgrade process or {@code null} * if none were removed. * if none were removed. */ */ public static Set<String> upgrade(int version, Map<Integer, SettingsUpgrader> upgraders, public static Set<String> upgrade(int version, Map<Integer, SettingsUpgrader> customUpgraders, Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, Object> validatedSettingsMutable) { Map<String, Object> validatedSettingsMutable) { Set<String> deletedSettings = null; Set<String> deletedSettings = null; for (int toVersion = version + 1; toVersion <= VERSION; toVersion++) { for (int toVersion = version + 1; toVersion <= VERSION; toVersion++) { if (customUpgraders.containsKey(toVersion)) { // Check if there's an SettingsUpgrader for that version SettingsUpgrader upgrader = customUpgraders.get(toVersion); SettingsUpgrader upgrader = upgraders.get(toVersion); if (upgrader != null) { deletedSettings = upgrader.upgrade(validatedSettingsMutable); deletedSettings = upgrader.upgrade(validatedSettingsMutable); } } // Deal with settings that don't need special upgrade code deletedSettings = upgradeSettingsGeneric(settings, validatedSettingsMutable, deletedSettings, toVersion); for (Entry<String, TreeMap<Integer, SettingsDescription>> versions : } settings.entrySet()) { return deletedSettings; } private static Set<String> upgradeSettingsGeneric(Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, Object> validatedSettingsMutable, Set<String> deletedSettingsMutable, int toVersion) { for (Entry<String, TreeMap<Integer, SettingsDescription>> versions : settings.entrySet()) { String settingName = versions.getKey(); String settingName = versions.getKey(); TreeMap<Integer, SettingsDescription> versionedSettings = versions.getValue(); TreeMap<Integer, SettingsDescription> versionedSettings = versions.getValue(); // Handle newly added settings boolean isNewlyAddedSetting = versionedSettings.firstKey() == toVersion; if (versionedSettings.firstKey() == toVersion) { if (isNewlyAddedSetting) { boolean wasHandledByCustomUpgrader = validatedSettingsMutable.containsKey(settingName); if (wasHandledByCustomUpgrader) { continue; } // Check if it was already added to upgradedSettings by the SettingsUpgrader if (!validatedSettingsMutable.containsKey(settingName)) { // Insert default value to upgradedSettings SettingsDescription setting = versionedSettings.get(toVersion); SettingsDescription setting = versionedSettings.get(toVersion); Object defaultValue = setting.getDefaultValue(); upgradeSettingInsertDefault(validatedSettingsMutable, settingName, setting); } Integer highestVersion = versionedSettings.lastKey(); boolean isRemovedSetting = highestVersion == toVersion && versionedSettings.get(highestVersion) == null; if (isRemovedSetting) { if (deletedSettingsMutable == null) { deletedSettingsMutable = new HashSet<>(); } upgradeSettingRemove(validatedSettingsMutable, deletedSettingsMutable, settingName); } } return deletedSettingsMutable; } private static <A> void upgradeSettingInsertDefault(Map<String, Object> validatedSettingsMutable, String settingName, SettingsDescription<A> setting) { A defaultValue = setting.getDefaultValue(); validatedSettingsMutable.put(settingName, defaultValue); validatedSettingsMutable.put(settingName, defaultValue); if (K9.DEBUG) { if (K9.DEBUG) { String prettyValue = setting.toPrettyString(defaultValue); String prettyValue = setting.toPrettyString(defaultValue); Log.v(K9.LOG_TAG, "Added new setting \"" + settingName + Log.v(K9.LOG_TAG, "Added new setting \"" + settingName + "\" with default value \"" + prettyValue + "\""); "\" with default value \"" + prettyValue + "\""); } } } } } // Handle removed settings private static void upgradeSettingRemove(Map<String, Object> validatedSettingsMutable, Integer highestVersion = versionedSettings.lastKey(); Set<String> deletedSettingsMutable, String settingName) { if (highestVersion == toVersion && versionedSettings.get(highestVersion) == null) { validatedSettingsMutable.remove(settingName); validatedSettingsMutable.remove(settingName); if (deletedSettings == null) { deletedSettingsMutable.add(settingName); deletedSettings = new HashSet<>(); } deletedSettings.add(settingName); if (K9.DEBUG) { if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Removed setting \"" + settingName + "\""); Log.v(K9.LOG_TAG, "Removed setting \"" + settingName + "\""); } } } } } } return deletedSettings; } /** /** * Convert settings from the internal representation to the string representation used in the * Convert settings from the internal representation to the string representation used in the Loading @@ -183,7 +192,6 @@ public class Settings { */ */ public static Map<String, String> convert(Map<String, Object> settings, public static Map<String, String> convert(Map<String, Object> settings, Map<String, TreeMap<Integer, SettingsDescription>> settingDescriptions) { Map<String, TreeMap<Integer, SettingsDescription>> settingDescriptions) { Map<String, String> serializedSettings = new HashMap<>(); Map<String, String> serializedSettings = new HashMap<>(); for (Entry<String, Object> setting : settings.entrySet()) { for (Entry<String, Object> setting : settings.entrySet()) { Loading Loading
k9mail/src/main/java/com/fsck/k9/preferences/Settings.java +52 −44 Original line number Original line Diff line number Diff line Loading @@ -99,7 +99,7 @@ public class Settings { * * * @param version * @param version * The content version of the settings in {@code validatedSettingsMutable}. * The content version of the settings in {@code validatedSettingsMutable}. * @param upgraders * @param customUpgraders * A map of {@link SettingsUpgrader}s for nontrivial settings upgrades. * A map of {@link SettingsUpgrader}s for nontrivial settings upgrades. * @param settings * @param settings * The structure describing the different settings, possibly containing multiple * The structure describing the different settings, possibly containing multiple Loading @@ -111,63 +111,72 @@ public class Settings { * @return A set of setting names that were removed during the upgrade process or {@code null} * @return A set of setting names that were removed during the upgrade process or {@code null} * if none were removed. * if none were removed. */ */ public static Set<String> upgrade(int version, Map<Integer, SettingsUpgrader> upgraders, public static Set<String> upgrade(int version, Map<Integer, SettingsUpgrader> customUpgraders, Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, Object> validatedSettingsMutable) { Map<String, Object> validatedSettingsMutable) { Set<String> deletedSettings = null; Set<String> deletedSettings = null; for (int toVersion = version + 1; toVersion <= VERSION; toVersion++) { for (int toVersion = version + 1; toVersion <= VERSION; toVersion++) { if (customUpgraders.containsKey(toVersion)) { // Check if there's an SettingsUpgrader for that version SettingsUpgrader upgrader = customUpgraders.get(toVersion); SettingsUpgrader upgrader = upgraders.get(toVersion); if (upgrader != null) { deletedSettings = upgrader.upgrade(validatedSettingsMutable); deletedSettings = upgrader.upgrade(validatedSettingsMutable); } } // Deal with settings that don't need special upgrade code deletedSettings = upgradeSettingsGeneric(settings, validatedSettingsMutable, deletedSettings, toVersion); for (Entry<String, TreeMap<Integer, SettingsDescription>> versions : } settings.entrySet()) { return deletedSettings; } private static Set<String> upgradeSettingsGeneric(Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, Object> validatedSettingsMutable, Set<String> deletedSettingsMutable, int toVersion) { for (Entry<String, TreeMap<Integer, SettingsDescription>> versions : settings.entrySet()) { String settingName = versions.getKey(); String settingName = versions.getKey(); TreeMap<Integer, SettingsDescription> versionedSettings = versions.getValue(); TreeMap<Integer, SettingsDescription> versionedSettings = versions.getValue(); // Handle newly added settings boolean isNewlyAddedSetting = versionedSettings.firstKey() == toVersion; if (versionedSettings.firstKey() == toVersion) { if (isNewlyAddedSetting) { boolean wasHandledByCustomUpgrader = validatedSettingsMutable.containsKey(settingName); if (wasHandledByCustomUpgrader) { continue; } // Check if it was already added to upgradedSettings by the SettingsUpgrader if (!validatedSettingsMutable.containsKey(settingName)) { // Insert default value to upgradedSettings SettingsDescription setting = versionedSettings.get(toVersion); SettingsDescription setting = versionedSettings.get(toVersion); Object defaultValue = setting.getDefaultValue(); upgradeSettingInsertDefault(validatedSettingsMutable, settingName, setting); } Integer highestVersion = versionedSettings.lastKey(); boolean isRemovedSetting = highestVersion == toVersion && versionedSettings.get(highestVersion) == null; if (isRemovedSetting) { if (deletedSettingsMutable == null) { deletedSettingsMutable = new HashSet<>(); } upgradeSettingRemove(validatedSettingsMutable, deletedSettingsMutable, settingName); } } return deletedSettingsMutable; } private static <A> void upgradeSettingInsertDefault(Map<String, Object> validatedSettingsMutable, String settingName, SettingsDescription<A> setting) { A defaultValue = setting.getDefaultValue(); validatedSettingsMutable.put(settingName, defaultValue); validatedSettingsMutable.put(settingName, defaultValue); if (K9.DEBUG) { if (K9.DEBUG) { String prettyValue = setting.toPrettyString(defaultValue); String prettyValue = setting.toPrettyString(defaultValue); Log.v(K9.LOG_TAG, "Added new setting \"" + settingName + Log.v(K9.LOG_TAG, "Added new setting \"" + settingName + "\" with default value \"" + prettyValue + "\""); "\" with default value \"" + prettyValue + "\""); } } } } } // Handle removed settings private static void upgradeSettingRemove(Map<String, Object> validatedSettingsMutable, Integer highestVersion = versionedSettings.lastKey(); Set<String> deletedSettingsMutable, String settingName) { if (highestVersion == toVersion && versionedSettings.get(highestVersion) == null) { validatedSettingsMutable.remove(settingName); validatedSettingsMutable.remove(settingName); if (deletedSettings == null) { deletedSettingsMutable.add(settingName); deletedSettings = new HashSet<>(); } deletedSettings.add(settingName); if (K9.DEBUG) { if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Removed setting \"" + settingName + "\""); Log.v(K9.LOG_TAG, "Removed setting \"" + settingName + "\""); } } } } } } return deletedSettings; } /** /** * Convert settings from the internal representation to the string representation used in the * Convert settings from the internal representation to the string representation used in the Loading @@ -183,7 +192,6 @@ public class Settings { */ */ public static Map<String, String> convert(Map<String, Object> settings, public static Map<String, String> convert(Map<String, Object> settings, Map<String, TreeMap<Integer, SettingsDescription>> settingDescriptions) { Map<String, TreeMap<Integer, SettingsDescription>> settingDescriptions) { Map<String, String> serializedSettings = new HashMap<>(); Map<String, String> serializedSettings = new HashMap<>(); for (Entry<String, Object> setting : settings.entrySet()) { for (Entry<String, Object> setting : settings.entrySet()) { Loading