From d5197fdc56ca118879bd1e4e7cc8e754c736b905 Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 30 Mar 2011 21:00:34 +0200 Subject: [PATCH] Put all import code in StorageImporter Get rid of StorageImporterEncryptedXml and IStorageImporter. Also AsyncUIProcessor is now obsolete. --- .../fsck/k9/activity/AsyncUIProcessor.java | 104 ------------ .../fsck/k9/preferences/IStorageImporter.java | 11 -- .../fsck/k9/preferences/StorageImporter.java | 152 ++++++++++-------- .../StorageImporterEncryptedXml.java | 102 ------------ 4 files changed, 85 insertions(+), 284 deletions(-) delete mode 100644 src/com/fsck/k9/activity/AsyncUIProcessor.java delete mode 100644 src/com/fsck/k9/preferences/IStorageImporter.java delete mode 100644 src/com/fsck/k9/preferences/StorageImporterEncryptedXml.java diff --git a/src/com/fsck/k9/activity/AsyncUIProcessor.java b/src/com/fsck/k9/activity/AsyncUIProcessor.java deleted file mode 100644 index a9108dcb5..000000000 --- a/src/com/fsck/k9/activity/AsyncUIProcessor.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.fsck.k9.activity; - -import java.io.InputStream; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import android.app.Activity; -import android.app.Application; -import android.content.ContentResolver; -import android.net.Uri; -import android.util.Log; - -import com.fsck.k9.K9; -import com.fsck.k9.preferences.StorageImporter; - -/** - * The class should be used to run long-running processes invoked from the UI that - * do not affect the Stores. There are probably pieces of MessagingController - * that can be moved here. - * - */ -public class AsyncUIProcessor { - - private final ExecutorService threadPool = Executors.newCachedThreadPool(); - private Application mApplication; - private static AsyncUIProcessor inst = null; - private AsyncUIProcessor(Application application) { - mApplication = application; - } - public synchronized static AsyncUIProcessor getInstance(Application application) { - if (inst == null) { - inst = new AsyncUIProcessor(application); - } - return inst; - } - public void execute(Runnable runnable) { - threadPool.execute(runnable); - } - - public void importSettings(final Activity activity, final Uri uri, final ImportListener listener) { - threadPool.execute(new Runnable() { - @Override - public void run() { - InputStream is = null; - try { - ContentResolver resolver = mApplication.getContentResolver(); - is = resolver.openInputStream(uri); - } catch (Exception e) { - Log.w(K9.LOG_TAG, "Exception while resolving Uri to InputStream", e); - if (listener != null) { - listener.failure(e.getLocalizedMessage(), e); - } - return; - } - final InputStream myIs = is; - StorageImporter.importPreferences(activity, is, null, new ImportListener() { - @Override - public void failure(String message, Exception e) { - quietClose(myIs); - if (listener != null) { - listener.failure(message, e); - } - } - - @Override - public void success(int numAccounts) { - quietClose(myIs); - if (listener != null) { - listener.success(numAccounts); - } - } - - @Override - public void canceled() { - quietClose(myIs); - if (listener != null) { - listener.canceled(); - } - } - - @Override - public void started() { - if (listener != null) { - listener.started(); - } - } - }); - } - } - ); - } - - private void quietClose(InputStream is) { - if (is != null) { - try { - is.close(); - } catch (Exception e) { - Log.w(K9.LOG_TAG, "Unable to close inputStream", e); - } - } - } - - -} diff --git a/src/com/fsck/k9/preferences/IStorageImporter.java b/src/com/fsck/k9/preferences/IStorageImporter.java deleted file mode 100644 index 415ad9bdc..000000000 --- a/src/com/fsck/k9/preferences/IStorageImporter.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.fsck.k9.preferences; - -import com.fsck.k9.Preferences; -import com.fsck.k9.preferences.StorageImporter.ImportElement; - -import android.content.SharedPreferences; - -public interface IStorageImporter { - public boolean needsKey(); - public abstract int importPreferences(Preferences preferences, SharedPreferences.Editor context, ImportElement dataset, String encryptionKey) throws StorageImportExportException; -} \ No newline at end of file diff --git a/src/com/fsck/k9/preferences/StorageImporter.java b/src/com/fsck/k9/preferences/StorageImporter.java index e1142e19f..f87183e20 100644 --- a/src/com/fsck/k9/preferences/StorageImporter.java +++ b/src/com/fsck/k9/preferences/StorageImporter.java @@ -1,9 +1,13 @@ package com.fsck.k9.preferences; +import java.io.BufferedReader; import java.io.InputStream; +import java.io.StringReader; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Stack; +import java.util.UUID; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -14,21 +18,21 @@ import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; -import android.app.Activity; +import android.content.Context; import android.content.SharedPreferences; import android.util.Log; +import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.Preferences; -import com.fsck.k9.R; -import com.fsck.k9.activity.AsyncUIProcessor; -import com.fsck.k9.activity.ImportListener; -import com.fsck.k9.activity.PasswordEntryDialog; import com.fsck.k9.helper.DateFormatter; public class StorageImporter { - public static void importPreferences(Activity activity, InputStream is, String providedEncryptionKey, ImportListener listener) { + public static void importPreferences(Context context, InputStream is, String encryptionKey, + boolean globalSettings, String[] importAccountUuids, boolean overwrite) + throws StorageImportExportException { + try { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); @@ -42,74 +46,88 @@ public class StorageImporter { String storageFormat = dataset.attributes.get("version"); Log.i(K9.LOG_TAG, "Got settings file version " + storageFormat); - IStorageImporter storageImporter = new StorageImporterEncryptedXml(); - if (storageImporter.needsKey() && providedEncryptionKey == null) { - gatherPassword(activity, storageImporter, dataset, listener); - } else { - finishImport(activity, storageImporter, dataset, providedEncryptionKey, listener); - } - } catch (Exception e) { - if (listener != null) { - listener.failure(e.getLocalizedMessage(), e); - } - } - } + Preferences preferences = Preferences.getPreferences(context); + SharedPreferences storage = preferences.getPreferences(); + SharedPreferences.Editor editor = storage.edit(); - private static void finishImport(Activity context, IStorageImporter storageImporter, ImportElement dataset, String encryptionKey, ImportListener listener) throws StorageImportExportException { - if (listener != null) { - listener.started(); - } - Preferences preferences = Preferences.getPreferences(context); - SharedPreferences storage = preferences.getPreferences(); - SharedPreferences.Editor editor = storage.edit(); - int numAccounts = 0; - if (storageImporter != null) { - numAccounts = storageImporter.importPreferences(preferences, editor, dataset, encryptionKey); - } - editor.commit(); - Preferences.getPreferences(context).refreshAccounts(); - DateFormatter.clearChosenFormat(); - K9.loadPrefs(Preferences.getPreferences(context)); - K9.setServicesEnabled(context); - if (listener != null) { - listener.success(numAccounts); - } - } + String data = dataset.data.toString(); + List accountNumbers = Account.getExistingAccountNumbers(preferences); + Log.i(K9.LOG_TAG, "Existing accountNumbers = " + accountNumbers); + /** + * We translate UUIDs in the import file into new UUIDs in the local instance for the following reasons: + * 1) Accidentally importing the same file twice cannot damage settings in an existing account. + * (Say, an account that was imported two months ago and has since had significant settings changes.) + * 2) Importing a single file multiple times allows for creating multiple accounts from the same template. + * 3) Exporting an account and importing back into the same instance is a poor-man's account copy (until a real + * copy function is created, if ever) + */ + Map uuidMapping = new HashMap(); + String accountUuids = preferences.getPreferences().getString("accountUuids", null); - private static void gatherPassword(final Activity activity, final IStorageImporter storageImporter, final ImportElement dataset, final ImportListener listener) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - PasswordEntryDialog dialog = new PasswordEntryDialog(activity, activity.getString(R.string.settings_import_encryption_password_prompt), - new PasswordEntryDialog.PasswordEntryListener() { - public void passwordChosen(final String chosenPassword) { - AsyncUIProcessor.getInstance(activity.getApplication()).execute(new Runnable() { - @Override - public void run() { - try { - finishImport(activity, storageImporter, dataset, chosenPassword, listener); - } catch (Exception e) { - Log.w(K9.LOG_TAG, "Failure during import", e); - if (listener != null) { - listener.failure(e.getLocalizedMessage(), e); - } - } + StringReader sr = new StringReader(data); + BufferedReader br = new BufferedReader(sr); + String line = null; + int settingsImported = 0; + int numAccounts = 0; + K9Krypto krypto = new K9Krypto(encryptionKey, K9Krypto.MODE.DECRYPT); + do { + line = br.readLine(); + if (line != null) { + //Log.i(K9.LOG_TAG, "Got line " + line); + String[] comps = line.split(":"); + if (comps.length > 1) { + String keyEnc = comps[0]; + String valueEnc = comps[1]; + String key = krypto.decrypt(keyEnc); + String value = krypto.decrypt(valueEnc); + String[] keyParts = key.split("\\."); + if (keyParts.length > 1) { + String oldUuid = keyParts[0]; + String newUuid = uuidMapping.get(oldUuid); + if (newUuid == null) { + newUuid = UUID.randomUUID().toString(); + uuidMapping.put(oldUuid, newUuid); + + Log.i(K9.LOG_TAG, "Mapping oldUuid " + oldUuid + " to newUuid " + newUuid); } - }); - } - - public void cancel() { - if (listener != null) { - listener.canceled(); + keyParts[0] = newUuid; + if ("accountNumber".equals(keyParts[1])) { + int accountNumber = Account.findNewAccountNumber(accountNumbers); + accountNumbers.add(accountNumber); + value = Integer.toString(accountNumber); + accountUuids += (accountUuids.length() != 0 ? "," : "") + newUuid; + numAccounts++; + } + StringBuilder builder = new StringBuilder(); + for (String part : keyParts) { + if (builder.length() > 0) { + builder.append("."); + } + builder.append(part); + } + key = builder.toString(); } + //Log.i(K9.LOG_TAG, "Setting " + key + " = " + value); + settingsImported++; + editor.putString(key, value); } - }); + } - dialog.show(); - } - }); + } while (line != null); - }; + editor.putString("accountUuids", accountUuids); + Log.i(K9.LOG_TAG, "Imported " + settingsImported + " settings and " + numAccounts + " accounts"); + + editor.commit(); + Preferences.getPreferences(context).refreshAccounts(); + DateFormatter.clearChosenFormat(); + K9.loadPrefs(Preferences.getPreferences(context)); + K9.setServicesEnabled(context); + + } catch (Exception e) { + throw new StorageImportExportException(); + } + } public static class ImportElement { diff --git a/src/com/fsck/k9/preferences/StorageImporterEncryptedXml.java b/src/com/fsck/k9/preferences/StorageImporterEncryptedXml.java deleted file mode 100644 index 0707fa133..000000000 --- a/src/com/fsck/k9/preferences/StorageImporterEncryptedXml.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.fsck.k9.preferences; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import android.content.SharedPreferences; -import android.util.Log; - -import com.fsck.k9.Account; -import com.fsck.k9.K9; -import com.fsck.k9.Preferences; -import com.fsck.k9.preferences.StorageImporter.ImportElement; - -public class StorageImporterEncryptedXml implements IStorageImporter { - public int importPreferences(Preferences preferences, SharedPreferences.Editor editor, ImportElement dataset, String encryptionKey) throws StorageImportExportException { - try { - - String data = dataset.data.toString(); - List accountNumbers = Account.getExistingAccountNumbers(preferences); - Log.i(K9.LOG_TAG, "Existing accountNumbers = " + accountNumbers); - /** - * We translate UUIDs in the import file into new UUIDs in the local instance for the following reasons: - * 1) Accidentally importing the same file twice cannot damage settings in an existing account. - * (Say, an account that was imported two months ago and has since had significant settings changes.) - * 2) Importing a single file multiple times allows for creating multiple accounts from the same template. - * 3) Exporting an account and importing back into the same instance is a poor-man's account copy (until a real - * copy function is created, if ever) - */ - Map uuidMapping = new HashMap(); - String accountUuids = preferences.getPreferences().getString("accountUuids", null); - - StringReader sr = new StringReader(data); - BufferedReader br = new BufferedReader(sr); - String line = null; - int settingsImported = 0; - int numAccounts = 0; - K9Krypto krypto = new K9Krypto(encryptionKey, K9Krypto.MODE.DECRYPT); - do { - line = br.readLine(); - if (line != null) { - //Log.i(K9.LOG_TAG, "Got line " + line); - String[] comps = line.split(":"); - if (comps.length > 1) { - String keyEnc = comps[0]; - String valueEnc = comps[1]; - String key = krypto.decrypt(keyEnc); - String value = krypto.decrypt(valueEnc); - String[] keyParts = key.split("\\."); - if (keyParts.length > 1) { - String oldUuid = keyParts[0]; - String newUuid = uuidMapping.get(oldUuid); - if (newUuid == null) { - newUuid = UUID.randomUUID().toString(); - uuidMapping.put(oldUuid, newUuid); - - Log.i(K9.LOG_TAG, "Mapping oldUuid " + oldUuid + " to newUuid " + newUuid); - } - keyParts[0] = newUuid; - if ("accountNumber".equals(keyParts[1])) { - int accountNumber = Account.findNewAccountNumber(accountNumbers); - accountNumbers.add(accountNumber); - value = Integer.toString(accountNumber); - accountUuids += (accountUuids.length() != 0 ? "," : "") + newUuid; - numAccounts++; - } - StringBuilder builder = new StringBuilder(); - for (String part : keyParts) { - if (builder.length() > 0) { - builder.append("."); - } - builder.append(part); - } - key = builder.toString(); - } - //Log.i(K9.LOG_TAG, "Setting " + key + " = " + value); - settingsImported++; - editor.putString(key, value); - } - } - - } while (line != null); - - editor.putString("accountUuids", accountUuids); - Log.i(K9.LOG_TAG, "Imported " + settingsImported + " settings and " + numAccounts + " accounts"); - return numAccounts; - } catch (IOException ie) { - throw new StorageImportExportException("Unable to import settings", ie); - } catch (Exception e) { - throw new StorageImportExportException("Unable to decrypt settings", e); - } - } - - @Override - public boolean needsKey() { - return true; - } -}