public static Map<String, Object> validate( int version, Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, String> importedSettings, boolean useDefaultValues) { Map<String, Object> validatedSettings = new HashMap<String, Object>(); for (Map.Entry<String, TreeMap<Integer, SettingsDescription>> versionedSetting : settings.entrySet()) { // Get the setting description with the highest version lower than or equal to the // supplied content version. TreeMap<Integer, SettingsDescription> versions = versionedSetting.getValue(); SortedMap<Integer, SettingsDescription> headMap = versions.headMap(version + 1); // Skip this setting if it was introduced after 'version' if (headMap.isEmpty()) { continue; } Integer settingVersion = headMap.lastKey(); SettingsDescription desc = versions.get(settingVersion); // Skip this setting if it is no longer used in 'version' if (desc == null) { continue; } String key = versionedSetting.getKey(); boolean useDefaultValue; if (!importedSettings.containsKey(key)) { Log.v( K9.LOG_TAG, "Key \"" + key + "\" wasn't found in the imported file." + ((useDefaultValues) ? " Using default value." : "")); useDefaultValue = useDefaultValues; } else { String prettyValue = importedSettings.get(key); try { Object internalValue = desc.fromPrettyString(prettyValue); validatedSettings.put(key, internalValue); useDefaultValue = false; } catch (InvalidSettingValueException e) { Log.v( K9.LOG_TAG, "Key \"" + key + "\" has invalid value \"" + prettyValue + "\" in imported file. " + ((useDefaultValues) ? "Using default value." : "Skipping.")); useDefaultValue = useDefaultValues; } } if (useDefaultValue) { Object defaultValue = desc.getDefaultValue(); validatedSettings.put(key, defaultValue); } } return validatedSettings; }
/** * Upgrade settings using the settings structure and/or special upgrade code. * * @param version The content version of the settings in {@code validatedSettings}. * @param upgraders A map of {@link SettingsUpgrader}s for nontrivial settings upgrades. * @param settings The structure describing the different settings, possibly containing multiple * versions. * @param validatedSettings The settings as returned by {@link Settings#validate(int, Map, Map, * boolean)}. This map is modified and contains the upgraded settings when this method * returns. * @return A set of setting names that were removed during the upgrade process or {@code null} if * none were removed. */ public static Set<String> upgrade( int version, Map<Integer, SettingsUpgrader> upgraders, Map<String, TreeMap<Integer, SettingsDescription>> settings, Map<String, Object> validatedSettings) { Map<String, Object> upgradedSettings = validatedSettings; Set<String> deletedSettings = null; for (int toVersion = version + 1; toVersion <= VERSION; toVersion++) { // Check if there's an SettingsUpgrader for that version SettingsUpgrader upgrader = upgraders.get(toVersion); if (upgrader != null) { deletedSettings = upgrader.upgrade(upgradedSettings); } // Deal with settings that don't need special upgrade code for (Entry<String, TreeMap<Integer, SettingsDescription>> versions : settings.entrySet()) { String settingName = versions.getKey(); TreeMap<Integer, SettingsDescription> versionedSettings = versions.getValue(); // Handle newly added settings if (versionedSettings.firstKey().intValue() == toVersion) { // Check if it was already added to upgradedSettings by the SettingsUpgrader if (!upgradedSettings.containsKey(settingName)) { // Insert default value to upgradedSettings SettingsDescription setting = versionedSettings.get(toVersion); Object defaultValue = setting.getDefaultValue(); upgradedSettings.put(settingName, defaultValue); if (K9.DEBUG) { String prettyValue = setting.toPrettyString(defaultValue); Log.v( K9.LOG_TAG, "Added new setting \"" + settingName + "\" with default value \"" + prettyValue + "\""); } } } // Handle removed settings Integer highestVersion = versionedSettings.lastKey(); if (highestVersion.intValue() == toVersion && versionedSettings.get(highestVersion) == null) { upgradedSettings.remove(settingName); if (deletedSettings == null) { deletedSettings = new HashSet<String>(); } deletedSettings.add(settingName); if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Removed setting \"" + settingName + "\""); } } } } return deletedSettings; }