Search in sources :

Example 1 with InvalidSettingValueException

use of com.fsck.k9.preferences.Settings.InvalidSettingValueException in project k-9 by k9mail.

the class SettingsImporter method importSettings.

/**
     * Reads an import {@link InputStream} and imports the global settings and/or account
     * configurations specified by the arguments.
     *
     * @param context
     *         A {@link Context} instance.
     * @param inputStream
     *         The {@code InputStream} to read the settings from.
     * @param globalSettings
     *         {@code true} if global settings should be imported from the file.
     * @param accountUuids
     *         A list of UUIDs of the accounts that should be imported.
     * @param overwrite
     *         {@code true} if existing accounts should be overwritten when an account with the
     *         same UUID is found in the settings file.<br>
     *         <strong>Note:</strong> This can have side-effects we currently don't handle, e.g.
     *         changing the account type from IMAP to POP3. So don't use this for now!
     *
     * @return An {@link ImportResults} instance containing information about errors and
     *         successfully imported accounts.
     *
     * @throws SettingsImportExportException
     *         In case of an error.
     */
public static ImportResults importSettings(Context context, InputStream inputStream, boolean globalSettings, List<String> accountUuids, boolean overwrite) throws SettingsImportExportException {
    try {
        boolean globalSettingsImported = false;
        List<AccountDescriptionPair> importedAccounts = new ArrayList<>();
        List<AccountDescription> erroneousAccounts = new ArrayList<>();
        Imported imported = parseSettings(inputStream, globalSettings, accountUuids, false);
        Preferences preferences = Preferences.getPreferences(context);
        Storage storage = preferences.getStorage();
        if (globalSettings) {
            try {
                StorageEditor editor = storage.edit();
                if (imported.globalSettings != null) {
                    importGlobalSettings(storage, editor, imported.contentVersion, imported.globalSettings);
                } else {
                    Timber.w("Was asked to import global settings but none found.");
                }
                if (editor.commit()) {
                    Timber.v("Committed global settings to the preference storage.");
                    globalSettingsImported = true;
                } else {
                    Timber.v("Failed to commit global settings to the preference storage");
                }
            } catch (Exception e) {
                Timber.e(e, "Exception while importing global settings");
            }
        }
        if (accountUuids != null && accountUuids.size() > 0) {
            if (imported.accounts != null) {
                for (String accountUuid : accountUuids) {
                    if (imported.accounts.containsKey(accountUuid)) {
                        ImportedAccount account = imported.accounts.get(accountUuid);
                        try {
                            StorageEditor editor = storage.edit();
                            AccountDescriptionPair importResult = importAccount(context, editor, imported.contentVersion, account, overwrite);
                            if (editor.commit()) {
                                Timber.v("Committed settings for account \"%s\" to the settings database.", importResult.imported.name);
                                // account UUIDs
                                if (!importResult.overwritten) {
                                    editor = storage.edit();
                                    String newUuid = importResult.imported.uuid;
                                    String oldAccountUuids = storage.getString("accountUuids", "");
                                    String newAccountUuids = (oldAccountUuids.length() > 0) ? oldAccountUuids + "," + newUuid : newUuid;
                                    putString(editor, "accountUuids", newAccountUuids);
                                    if (!editor.commit()) {
                                        throw new SettingsImportExportException("Failed to set account UUID list");
                                    }
                                }
                                // Reload accounts
                                preferences.loadAccounts();
                                importedAccounts.add(importResult);
                            } else {
                                Timber.w("Error while committing settings for account \"%s\" to the settings " + "database.", importResult.original.name);
                                erroneousAccounts.add(importResult.original);
                            }
                        } catch (InvalidSettingValueException e) {
                            Timber.e(e, "Encountered invalid setting while importing account \"%s\"", account.name);
                            erroneousAccounts.add(new AccountDescription(account.name, account.uuid));
                        } catch (Exception e) {
                            Timber.e(e, "Exception while importing account \"%s\"", account.name);
                            erroneousAccounts.add(new AccountDescription(account.name, account.uuid));
                        }
                    } else {
                        Timber.w("Was asked to import account with UUID %s. But this account wasn't found.", accountUuid);
                    }
                }
                StorageEditor editor = storage.edit();
                String defaultAccountUuid = storage.getString("defaultAccountUuid", null);
                if (defaultAccountUuid == null) {
                    putString(editor, "defaultAccountUuid", accountUuids.get(0));
                }
                if (!editor.commit()) {
                    throw new SettingsImportExportException("Failed to set default account");
                }
            } else {
                Timber.w("Was asked to import at least one account but none found.");
            }
        }
        preferences.loadAccounts();
        K9.loadPrefs(preferences);
        K9.setServicesEnabled(context);
        return new ImportResults(globalSettingsImported, importedAccounts, erroneousAccounts);
    } catch (SettingsImportExportException e) {
        throw e;
    } catch (Exception e) {
        throw new SettingsImportExportException(e);
    }
}
Also used : ArrayList(java.util.ArrayList) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) IOException(java.io.IOException) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) SharedPreferences(android.content.SharedPreferences) Preferences(com.fsck.k9.Preferences)

Example 2 with InvalidSettingValueException

use of com.fsck.k9.preferences.Settings.InvalidSettingValueException in project k-9 by k9mail.

the class SettingsExporter method writeSettings.

private static void writeSettings(XmlSerializer serializer, Map<String, Object> prefs) throws IOException {
    for (Entry<String, TreeMap<Integer, SettingsDescription>> versionedSetting : GlobalSettings.SETTINGS.entrySet()) {
        String key = versionedSetting.getKey();
        String valueString = (String) prefs.get(key);
        TreeMap<Integer, SettingsDescription> versions = versionedSetting.getValue();
        Integer highestVersion = versions.lastKey();
        SettingsDescription setting = versions.get(highestVersion);
        if (setting == null) {
            // Setting was removed.
            continue;
        }
        if (valueString != null) {
            try {
                writeKeyAndPrettyValueFromSetting(serializer, key, setting, valueString);
            } catch (InvalidSettingValueException e) {
                Timber.w("Global setting \"%s\" has invalid value \"%s\" in preference storage. " + "This shouldn't happen!", key, valueString);
            }
        } else {
            Timber.d("Couldn't find key \"%s\" in preference storage. Using default value.", key);
            writeKeyAndDefaultValueFromSetting(serializer, key, setting);
        }
    }
}
Also used : SettingsDescription(com.fsck.k9.preferences.Settings.SettingsDescription) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) TreeMap(java.util.TreeMap)

Example 3 with InvalidSettingValueException

use of com.fsck.k9.preferences.Settings.InvalidSettingValueException in project k-9 by k9mail.

the class SettingsExporter method writeAccount.

private static void writeAccount(XmlSerializer serializer, Account account, Map<String, Object> prefs) throws IOException {
    Set<Integer> identities = new HashSet<>();
    Set<String> folders = new HashSet<>();
    String accountUuid = account.getUuid();
    serializer.startTag(null, ACCOUNT_ELEMENT);
    serializer.attribute(null, UUID_ATTRIBUTE, accountUuid);
    String name = (String) prefs.get(accountUuid + "." + Account.ACCOUNT_DESCRIPTION_KEY);
    if (name != null) {
        serializer.startTag(null, NAME_ELEMENT);
        serializer.text(name);
        serializer.endTag(null, NAME_ELEMENT);
    }
    // Write incoming server settings
    ServerSettings incoming = RemoteStore.decodeStoreUri(account.getStoreUri());
    serializer.startTag(null, INCOMING_SERVER_ELEMENT);
    serializer.attribute(null, TYPE_ATTRIBUTE, incoming.type.name());
    writeElement(serializer, HOST_ELEMENT, incoming.host);
    if (incoming.port != -1) {
        writeElement(serializer, PORT_ELEMENT, Integer.toString(incoming.port));
    }
    if (incoming.connectionSecurity != null) {
        writeElement(serializer, CONNECTION_SECURITY_ELEMENT, incoming.connectionSecurity.name());
    }
    if (incoming.authenticationType != null) {
        writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, incoming.authenticationType.name());
    }
    writeElement(serializer, USERNAME_ELEMENT, incoming.username);
    writeElement(serializer, CLIENT_CERTIFICATE_ALIAS_ELEMENT, incoming.clientCertificateAlias);
    // XXX For now we don't export the password
    //writeElement(serializer, PASSWORD_ELEMENT, incoming.password);
    Map<String, String> extras = incoming.getExtra();
    if (extras != null && extras.size() > 0) {
        serializer.startTag(null, EXTRA_ELEMENT);
        for (Entry<String, String> extra : extras.entrySet()) {
            writeKeyAndPrettyValueFromSetting(serializer, extra.getKey(), extra.getValue());
        }
        serializer.endTag(null, EXTRA_ELEMENT);
    }
    serializer.endTag(null, INCOMING_SERVER_ELEMENT);
    // Write outgoing server settings
    ServerSettings outgoing = Transport.decodeTransportUri(account.getTransportUri());
    serializer.startTag(null, OUTGOING_SERVER_ELEMENT);
    serializer.attribute(null, TYPE_ATTRIBUTE, outgoing.type.name());
    writeElement(serializer, HOST_ELEMENT, outgoing.host);
    if (outgoing.port != -1) {
        writeElement(serializer, PORT_ELEMENT, Integer.toString(outgoing.port));
    }
    if (outgoing.connectionSecurity != null) {
        writeElement(serializer, CONNECTION_SECURITY_ELEMENT, outgoing.connectionSecurity.name());
    }
    if (outgoing.authenticationType != null) {
        writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, outgoing.authenticationType.name());
    }
    writeElement(serializer, USERNAME_ELEMENT, outgoing.username);
    writeElement(serializer, CLIENT_CERTIFICATE_ALIAS_ELEMENT, outgoing.clientCertificateAlias);
    // XXX For now we don't export the password
    //writeElement(serializer, PASSWORD_ELEMENT, outgoing.password);
    extras = outgoing.getExtra();
    if (extras != null && extras.size() > 0) {
        serializer.startTag(null, EXTRA_ELEMENT);
        for (Entry<String, String> extra : extras.entrySet()) {
            writeKeyAndPrettyValueFromSetting(serializer, extra.getKey(), extra.getValue());
        }
        serializer.endTag(null, EXTRA_ELEMENT);
    }
    serializer.endTag(null, OUTGOING_SERVER_ELEMENT);
    // Write account settings
    serializer.startTag(null, SETTINGS_ELEMENT);
    for (Map.Entry<String, Object> entry : prefs.entrySet()) {
        String key = entry.getKey();
        String valueString = entry.getValue().toString();
        String[] comps = key.split("\\.", 2);
        if (comps.length < 2) {
            // Skip global settings
            continue;
        }
        String keyUuid = comps[0];
        String keyPart = comps[1];
        if (!keyUuid.equals(accountUuid)) {
            // Setting doesn't belong to the account we're currently writing.
            continue;
        }
        int indexOfLastDot = keyPart.lastIndexOf(".");
        boolean hasThirdPart = indexOfLastDot != -1 && indexOfLastDot < keyPart.length() - 1;
        if (hasThirdPart) {
            String secondPart = keyPart.substring(0, indexOfLastDot);
            String thirdPart = keyPart.substring(indexOfLastDot + 1);
            if (Account.IDENTITY_DESCRIPTION_KEY.equals(secondPart)) {
                // This is an identity key. Save identity index for later...
                try {
                    identities.add(Integer.parseInt(thirdPart));
                } catch (NumberFormatException e) {
                /* ignore */
                }
                // ... but don't write it now.
                continue;
            }
            if (FolderSettings.SETTINGS.containsKey(thirdPart)) {
                // This is a folder key. Save folder name for later...
                folders.add(secondPart);
                // ... but don't write it now.
                continue;
            }
        }
        TreeMap<Integer, SettingsDescription> versionedSetting = AccountSettings.SETTINGS.get(keyPart);
        if (versionedSetting != null) {
            Integer highestVersion = versionedSetting.lastKey();
            SettingsDescription setting = versionedSetting.get(highestVersion);
            if (setting != null) {
                // Only export account settings that can be found in AccountSettings.SETTINGS
                try {
                    writeKeyAndPrettyValueFromSetting(serializer, keyPart, setting, valueString);
                } catch (InvalidSettingValueException e) {
                    Timber.w("Account setting \"%s\" (%s) has invalid value \"%s\" in preference storage. " + "This shouldn't happen!", keyPart, account.getDescription(), valueString);
                }
            }
        }
    }
    serializer.endTag(null, SETTINGS_ELEMENT);
    if (identities.size() > 0) {
        serializer.startTag(null, IDENTITIES_ELEMENT);
        // Sort identity indices (that's why we store them as Integers)
        List<Integer> sortedIdentities = new ArrayList<>(identities);
        Collections.sort(sortedIdentities);
        for (Integer identityIndex : sortedIdentities) {
            writeIdentity(serializer, accountUuid, identityIndex.toString(), prefs);
        }
        serializer.endTag(null, IDENTITIES_ELEMENT);
    }
    if (folders.size() > 0) {
        serializer.startTag(null, FOLDERS_ELEMENT);
        for (String folder : folders) {
            writeFolder(serializer, accountUuid, folder, prefs);
        }
        serializer.endTag(null, FOLDERS_ELEMENT);
    }
    serializer.endTag(null, ACCOUNT_ELEMENT);
}
Also used : ArrayList(java.util.ArrayList) SettingsDescription(com.fsck.k9.preferences.Settings.SettingsDescription) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) ServerSettings(com.fsck.k9.mail.ServerSettings) Map(java.util.Map) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Example 4 with InvalidSettingValueException

use of com.fsck.k9.preferences.Settings.InvalidSettingValueException in project k-9 by k9mail.

the class SettingsExporter method writeIdentity.

private static void writeIdentity(XmlSerializer serializer, String accountUuid, String identity, Map<String, Object> prefs) throws IOException {
    serializer.startTag(null, IDENTITY_ELEMENT);
    String prefix = accountUuid + ".";
    String suffix = "." + identity;
    // Write name belonging to the identity
    String name = (String) prefs.get(prefix + Account.IDENTITY_NAME_KEY + suffix);
    serializer.startTag(null, NAME_ELEMENT);
    serializer.text(name);
    serializer.endTag(null, NAME_ELEMENT);
    // Write email address belonging to the identity
    String email = (String) prefs.get(prefix + Account.IDENTITY_EMAIL_KEY + suffix);
    serializer.startTag(null, EMAIL_ELEMENT);
    serializer.text(email);
    serializer.endTag(null, EMAIL_ELEMENT);
    // Write identity description
    String description = (String) prefs.get(prefix + Account.IDENTITY_DESCRIPTION_KEY + suffix);
    if (description != null) {
        serializer.startTag(null, DESCRIPTION_ELEMENT);
        serializer.text(description);
        serializer.endTag(null, DESCRIPTION_ELEMENT);
    }
    // Write identity settings
    serializer.startTag(null, SETTINGS_ELEMENT);
    for (Map.Entry<String, Object> entry : prefs.entrySet()) {
        String key = entry.getKey();
        String valueString = entry.getValue().toString();
        String[] comps = key.split("\\.");
        if (comps.length < 3) {
            // Skip non-identity config entries
            continue;
        }
        String keyUuid = comps[0];
        String identityKey = comps[1];
        String identityIndex = comps[2];
        if (!keyUuid.equals(accountUuid) || !identityIndex.equals(identity)) {
            // Skip entries that belong to another identity
            continue;
        }
        TreeMap<Integer, SettingsDescription> versionedSetting = IdentitySettings.SETTINGS.get(identityKey);
        if (versionedSetting != null) {
            Integer highestVersion = versionedSetting.lastKey();
            SettingsDescription setting = versionedSetting.get(highestVersion);
            if (setting != null) {
                // Only write settings that have an entry in IdentitySettings.SETTINGS
                try {
                    writeKeyAndPrettyValueFromSetting(serializer, identityKey, setting, valueString);
                } catch (InvalidSettingValueException e) {
                    Timber.w("Identity setting \"%s\" has invalid value \"%s\" in preference storage. " + "This shouldn't happen!", identityKey, valueString);
                }
            }
        }
    }
    serializer.endTag(null, SETTINGS_ELEMENT);
    serializer.endTag(null, IDENTITY_ELEMENT);
}
Also used : SettingsDescription(com.fsck.k9.preferences.Settings.SettingsDescription) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 5 with InvalidSettingValueException

use of com.fsck.k9.preferences.Settings.InvalidSettingValueException in project k-9 by k9mail.

the class SettingsExporter method writeFolder.

private static void writeFolder(XmlSerializer serializer, String accountUuid, String folder, Map<String, Object> prefs) throws IOException {
    serializer.startTag(null, FOLDER_ELEMENT);
    serializer.attribute(null, NAME_ATTRIBUTE, folder);
    // Write folder settings
    for (Map.Entry<String, Object> entry : prefs.entrySet()) {
        String key = entry.getKey();
        String valueString = entry.getValue().toString();
        int indexOfFirstDot = key.indexOf('.');
        int indexOfLastDot = key.lastIndexOf('.');
        if (indexOfFirstDot == -1 || indexOfLastDot == -1 || indexOfFirstDot == indexOfLastDot) {
            // Skip non-folder config entries
            continue;
        }
        String keyUuid = key.substring(0, indexOfFirstDot);
        String folderName = key.substring(indexOfFirstDot + 1, indexOfLastDot);
        String folderKey = key.substring(indexOfLastDot + 1);
        if (!keyUuid.equals(accountUuid) || !folderName.equals(folder)) {
            // Skip entries that belong to another folder
            continue;
        }
        TreeMap<Integer, SettingsDescription> versionedSetting = FolderSettings.SETTINGS.get(folderKey);
        if (versionedSetting != null) {
            Integer highestVersion = versionedSetting.lastKey();
            SettingsDescription setting = versionedSetting.get(highestVersion);
            if (setting != null) {
                // Only write settings that have an entry in FolderSettings.SETTINGS
                try {
                    writeKeyAndPrettyValueFromSetting(serializer, folderKey, setting, valueString);
                } catch (InvalidSettingValueException e) {
                    Timber.w("Folder setting \"%s\" has invalid value \"%s\" in preference storage. " + "This shouldn't happen!", folderKey, valueString);
                }
            }
        }
    }
    serializer.endTag(null, FOLDER_ELEMENT);
}
Also used : SettingsDescription(com.fsck.k9.preferences.Settings.SettingsDescription) InvalidSettingValueException(com.fsck.k9.preferences.Settings.InvalidSettingValueException) Map(java.util.Map) TreeMap(java.util.TreeMap)

Aggregations

InvalidSettingValueException (com.fsck.k9.preferences.Settings.InvalidSettingValueException)6 SettingsDescription (com.fsck.k9.preferences.Settings.SettingsDescription)4 Map (java.util.Map)4 TreeMap (java.util.TreeMap)4 SharedPreferences (android.content.SharedPreferences)2 Preferences (com.fsck.k9.Preferences)2 ServerSettings (com.fsck.k9.mail.ServerSettings)2 ArrayList (java.util.ArrayList)2 Account (com.fsck.k9.Account)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)1