diff options
author | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
commit | 302bf1b523012e11b60425d6eee1221ebc2724eb (patch) | |
tree | b191a895f8716efcbe42f454f37597a545a6f421 /mailnews/import/src/nsImportAddressBooks.cpp | |
parent | 21b3f6247403c06f85e1f45d219f87549862198f (diff) | |
download | UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.gz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.lz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.xz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.zip |
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
Diffstat (limited to 'mailnews/import/src/nsImportAddressBooks.cpp')
-rw-r--r-- | mailnews/import/src/nsImportAddressBooks.cpp | 894 |
1 files changed, 894 insertions, 0 deletions
diff --git a/mailnews/import/src/nsImportAddressBooks.cpp b/mailnews/import/src/nsImportAddressBooks.cpp new file mode 100644 index 000000000..8791efb42 --- /dev/null +++ b/mailnews/import/src/nsImportAddressBooks.cpp @@ -0,0 +1,894 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prprf.h" +#include "plstr.h" +#include "nsCOMPtr.h" +#include "nsMsgUtils.h" +#include "nsIImportService.h" +#include "nsIImportAddressBooks.h" +#include "nsIImportGeneric.h" +#include "nsISupportsPrimitives.h" +#include "nsIImportABDescriptor.h" +#include "nsIImportFieldMap.h" +#include "nsStringGlue.h" +#include "nsIFile.h" +#include "nsIAddrDatabase.h" +#include "nsIAbManager.h" +#include "nsIAbLDIFService.h" +#include "nsAbBaseCID.h" +#include "nsIStringBundle.h" +#include "nsImportStringBundle.h" +#include "nsTextFormatter.h" +#include "nsServiceManagerUtils.h" +#include "msgCore.h" +#include "ImportDebug.h" +#include "nsIAbMDBDirectory.h" +#include "nsComponentManagerUtils.h" +#include "nsIArray.h" +#include "nsCOMArray.h" +#include "nsArrayUtils.h" + +static void ImportAddressThread(void *stuff); + +class AddressThreadData; + +class nsImportGenericAddressBooks : public nsIImportGeneric +{ +public: + + nsImportGenericAddressBooks(); + + NS_DECL_THREADSAFE_ISUPPORTS + + /* nsISupports GetData (in string dataId); */ + NS_IMETHOD GetData(const char *dataId, nsISupports **_retval) override; + + NS_IMETHOD SetData(const char *dataId, nsISupports *pData) override; + + NS_IMETHOD GetStatus(const char *statusKind, int32_t *_retval) override; + + NS_IMETHOD WantsProgress(bool *_retval) override; + + NS_IMETHOD BeginImport(nsISupportsString *successLog, nsISupportsString *errorLog, bool *_retval) override; + + NS_IMETHOD ContinueImport(bool *_retval) override; + + NS_IMETHOD GetProgress(int32_t *_retval) override; + + NS_IMETHOD CancelImport(void) override; + +private: + virtual ~nsImportGenericAddressBooks(); + void GetDefaultLocation(void); + void GetDefaultBooks(void); + void GetDefaultFieldMap(void); + +public: + static void SetLogs(nsString& success, nsString& error, nsISupportsString *pSuccess, nsISupportsString *pError); + static void ReportError(const char16_t *pName, nsString *pStream, + nsIStringBundle *aBundle); + +private: + nsIImportAddressBooks * m_pInterface; + nsCOMPtr<nsIArray> m_Books; + nsCOMArray<nsIAddrDatabase> m_DBs; + nsCOMPtr <nsIFile> m_pLocation; + nsIImportFieldMap * m_pFieldMap; + bool m_autoFind; + char16_t * m_description; + bool m_gotLocation; + bool m_found; + bool m_userVerify; + nsISupportsString * m_pSuccessLog; + nsISupportsString * m_pErrorLog; + uint32_t m_totalSize; + bool m_doImport; + AddressThreadData * m_pThreadData; + char * m_pDestinationUri; + nsCOMPtr<nsIStringBundle> m_stringBundle; +}; + +class AddressThreadData { +public: + bool driverAlive; + bool threadAlive; + bool abort; + bool fatalError; + uint32_t currentTotal; + uint32_t currentSize; + nsIArray *books; + nsCOMArray<nsIAddrDatabase>* dBs; + nsCOMPtr<nsIAbLDIFService> ldifService; + nsIImportAddressBooks * addressImport; + nsIImportFieldMap * fieldMap; + nsISupportsString * successLog; + nsISupportsString * errorLog; + char * pDestinationUri; + nsIStringBundle* stringBundle; + + AddressThreadData(); + ~AddressThreadData(); +}; + + +nsresult NS_NewGenericAddressBooks(nsIImportGeneric** aImportGeneric) +{ + NS_PRECONDITION(aImportGeneric != nullptr, "null ptr"); + if (! aImportGeneric) + return NS_ERROR_NULL_POINTER; + + nsImportGenericAddressBooks *pGen = new nsImportGenericAddressBooks(); + + if (pGen == nullptr) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(pGen); + nsresult rv = pGen->QueryInterface(NS_GET_IID(nsIImportGeneric), (void **)aImportGeneric); + NS_RELEASE(pGen); + + return rv; +} + +nsImportGenericAddressBooks::nsImportGenericAddressBooks() +{ + m_pInterface = nullptr; + m_pSuccessLog = nullptr; + m_pErrorLog = nullptr; + m_totalSize = 0; + m_doImport = false; + m_pThreadData = nullptr; + m_pDestinationUri = nullptr; + m_pFieldMap = nullptr; + + m_autoFind = false; + m_description = nullptr; + m_gotLocation = false; + m_found = false; + m_userVerify = false; + + nsImportStringBundle::GetStringBundle(IMPORT_MSGS_URL, getter_AddRefs(m_stringBundle)); +} + + +nsImportGenericAddressBooks::~nsImportGenericAddressBooks() +{ + if (m_pDestinationUri) + NS_Free(m_pDestinationUri); + + if (m_description) + NS_Free(m_description); + + NS_IF_RELEASE(m_pFieldMap); + NS_IF_RELEASE(m_pInterface); + NS_IF_RELEASE(m_pSuccessLog); + NS_IF_RELEASE(m_pErrorLog); +} + + + +NS_IMPL_ISUPPORTS(nsImportGenericAddressBooks, nsIImportGeneric) + + +NS_IMETHODIMP nsImportGenericAddressBooks::GetData(const char *dataId, nsISupports **_retval) +{ + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!_retval) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + *_retval = nullptr; + if (!PL_strcasecmp(dataId, "addressInterface")) { + *_retval = m_pInterface; + NS_IF_ADDREF(m_pInterface); + } + + if (!PL_strcasecmp(dataId, "addressLocation")) { + if (!m_pLocation) + GetDefaultLocation(); + NS_IF_ADDREF(*_retval = m_pLocation); + } + + if (!PL_strcasecmp(dataId, "addressBooks")) { + if (!m_pLocation) + GetDefaultLocation(); + if (!m_Books) + GetDefaultBooks(); + *_retval = m_Books; + } + + if (!PL_strcasecmp(dataId, "addressDestination")) { + if (m_pDestinationUri) { + nsCOMPtr<nsISupportsCString> abString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + abString->SetData(nsDependentCString(m_pDestinationUri)); + NS_IF_ADDREF(*_retval = abString); + } + } + + if (!PL_strcasecmp(dataId, "fieldMap")) { + if (m_pFieldMap) { + *_retval = m_pFieldMap; + m_pFieldMap->AddRef(); + } + else { + if (m_pInterface && m_pLocation) { + bool needsIt = false; + m_pInterface->GetNeedsFieldMap(m_pLocation, &needsIt); + if (needsIt) { + GetDefaultFieldMap(); + if (m_pFieldMap) { + *_retval = m_pFieldMap; + m_pFieldMap->AddRef(); + } + } + } + } + } + + if (!PL_strncasecmp(dataId, "sampleData-", 11)) { + // extra the record number + const char *pNum = dataId + 11; + int32_t rNum = 0; + while (*pNum) { + rNum *= 10; + rNum += (*pNum - '0'); + pNum++; + } + IMPORT_LOG1("Requesting sample data #: %ld\n", (long)rNum); + if (m_pInterface) { + nsCOMPtr<nsISupportsString> data = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return rv; + char16_t * pData = nullptr; + bool found = false; + rv = m_pInterface->GetSampleData(rNum, &found, &pData); + if (NS_FAILED(rv)) + return rv; + if (found) { + data->SetData(nsDependentString(pData)); + *_retval = data; + NS_ADDREF(*_retval); + } + NS_Free(pData); + } + } + + return NS_OK; +} + + +NS_IMETHODIMP nsImportGenericAddressBooks::SetData(const char *dataId, nsISupports *item) +{ + NS_PRECONDITION(dataId != nullptr, "null ptr"); + if (!dataId) + return NS_ERROR_NULL_POINTER; + + if (!PL_strcasecmp(dataId, "addressInterface")) { + NS_IF_RELEASE(m_pInterface); + if (item) + item->QueryInterface(NS_GET_IID(nsIImportAddressBooks), (void **) &m_pInterface); + } + if (!PL_strcasecmp(dataId, "addressBooks")) { + if (item) + item->QueryInterface(NS_GET_IID(nsIArray), (void **) &m_Books); + } + + if (!PL_strcasecmp(dataId, "addressLocation")) { + m_pLocation = nullptr; + + if (item) { + nsresult rv; + m_pLocation = do_QueryInterface(item, &rv); + NS_ENSURE_SUCCESS(rv,rv); + } + + if (m_pInterface) + m_pInterface->SetSampleLocation(m_pLocation); + } + + if (!PL_strcasecmp(dataId, "addressDestination")) { + if (item) { + nsCOMPtr<nsISupportsCString> abString; + item->QueryInterface(NS_GET_IID(nsISupportsCString), getter_AddRefs(abString)); + if (abString) { + if (m_pDestinationUri) + NS_Free(m_pDestinationUri); + m_pDestinationUri = nullptr; + nsAutoCString tempUri; + abString->GetData(tempUri); + m_pDestinationUri = ToNewCString(tempUri); + } + } + } + + if (!PL_strcasecmp(dataId, "fieldMap")) { + NS_IF_RELEASE(m_pFieldMap); + if (item) + item->QueryInterface(NS_GET_IID(nsIImportFieldMap), (void **) &m_pFieldMap); + } + + return NS_OK; +} + +NS_IMETHODIMP nsImportGenericAddressBooks::GetStatus(const char *statusKind, int32_t *_retval) +{ + NS_PRECONDITION(statusKind != nullptr, "null ptr"); + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!statusKind || !_retval) + return NS_ERROR_NULL_POINTER; + + *_retval = 0; + + if (!PL_strcasecmp(statusKind, "isInstalled")) { + GetDefaultLocation(); + *_retval = (int32_t) m_found; + } + + if (!PL_strcasecmp(statusKind, "canUserSetLocation")) { + GetDefaultLocation(); + *_retval = (int32_t) m_userVerify; + } + + if (!PL_strcasecmp(statusKind, "autoFind")) { + GetDefaultLocation(); + *_retval = (int32_t) m_autoFind; + } + + if (!PL_strcasecmp(statusKind, "supportsMultiple")) { + bool multi = false; + if (m_pInterface) + m_pInterface->GetSupportsMultiple(&multi); + *_retval = (int32_t) multi; + } + + if (!PL_strcasecmp(statusKind, "needsFieldMap")) { + bool needs = false; + if (m_pInterface && m_pLocation) + m_pInterface->GetNeedsFieldMap(m_pLocation, &needs); + *_retval = (int32_t) needs; + } + + return NS_OK; +} + +void nsImportGenericAddressBooks::GetDefaultLocation(void) +{ + if (!m_pInterface) + return; + + if ((m_pLocation && m_gotLocation) || m_autoFind) + return; + + if (m_description) + NS_Free(m_description); + m_description = nullptr; + m_pInterface->GetAutoFind(&m_description, &m_autoFind); + m_gotLocation = true; + if (m_autoFind) { + m_found = true; + m_userVerify = false; + return; + } + + nsCOMPtr <nsIFile> pLoc; + m_pInterface->GetDefaultLocation(getter_AddRefs(pLoc), &m_found, &m_userVerify); + if (!m_pLocation) + m_pLocation = pLoc; +} + +void nsImportGenericAddressBooks::GetDefaultBooks(void) +{ + if (!m_pInterface || m_Books) + return; + + if (!m_pLocation && !m_autoFind) + return; + + nsresult rv = m_pInterface->FindAddressBooks(m_pLocation, getter_AddRefs(m_Books)); + if (NS_FAILED(rv)) { + IMPORT_LOG0("*** Error: FindAddressBooks failed\n"); + } +} + +void nsImportGenericAddressBooks::GetDefaultFieldMap(void) +{ + if (!m_pInterface || !m_pLocation) + return; + + NS_IF_RELEASE(m_pFieldMap); + + nsresult rv; + nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + IMPORT_LOG0("*** Unable to get nsIImportService.\n"); + return; + } + + rv = impSvc->CreateNewFieldMap(&m_pFieldMap); + if (NS_FAILED(rv)) + return; + + int32_t sz = 0; + rv = m_pFieldMap->GetNumMozFields(&sz); + if (NS_SUCCEEDED(rv)) + rv = m_pFieldMap->DefaultFieldMap(sz); + if (NS_SUCCEEDED(rv)) + rv = m_pInterface->InitFieldMap(m_pFieldMap); + if (NS_FAILED(rv)) { + IMPORT_LOG0("*** Error: Unable to initialize field map\n"); + NS_IF_RELEASE(m_pFieldMap); + } +} + + +NS_IMETHODIMP nsImportGenericAddressBooks::WantsProgress(bool *_retval) +{ + NS_PRECONDITION(_retval != nullptr, "null ptr"); + NS_ENSURE_ARG_POINTER(_retval); + + GetDefaultLocation(); + GetDefaultBooks(); + + bool result = false; + + if (m_Books) { + uint32_t count = 0; + uint32_t i; + bool import; + uint32_t size; + uint32_t totalSize = 0; + + m_Books->GetLength(&count); + + for (i = 0; i < count; i++) { + nsCOMPtr<nsIImportABDescriptor> book = do_QueryElementAt(m_Books, i); + if (book) { + import = false; + size = 0; + nsresult rv = book->GetImport(&import); + if (NS_SUCCEEDED(rv) && import) { + (void) book->GetSize(&size); + result = true; + } + totalSize += size; + } + } + + m_totalSize = totalSize; + } + + m_doImport = result; + + *_retval = result; + + return NS_OK; +} + +void nsImportGenericAddressBooks::SetLogs(nsString& success, nsString& error, nsISupportsString *pSuccess, nsISupportsString *pError) +{ + nsAutoString str; + if (pSuccess) { + pSuccess->GetData(str); + str.Append(success); + pSuccess->SetData(success); + } + if (pError) { + pError->GetData(str); + str.Append(error); + pError->SetData(error); + } +} + +already_AddRefed<nsIAddrDatabase> GetAddressBookFromUri(const char *pUri) +{ + if (!pUri) + return nullptr; + + nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID); + if (!abManager) + return nullptr; + + nsCOMPtr<nsIAbDirectory> directory; + abManager->GetDirectory(nsDependentCString(pUri), + getter_AddRefs(directory)); + if (!directory) + return nullptr; + + nsCOMPtr<nsIAbMDBDirectory> mdbDirectory = do_QueryInterface(directory); + if (!mdbDirectory) + return nullptr; + + nsCOMPtr<nsIAddrDatabase> pDatabase; + mdbDirectory->GetDatabase(getter_AddRefs(pDatabase)); + return pDatabase.forget(); +} + +already_AddRefed<nsIAddrDatabase> GetAddressBook(const char16_t *name, + bool makeNew) +{ + if (!makeNew) { + // FIXME: How do I get the list of address books and look for a + // specific name. Major bogosity! + // For now, assume we didn't find anything with that name + } + + IMPORT_LOG0("In GetAddressBook\n"); + + nsresult rv; + nsCOMPtr<nsIAddrDatabase> pDatabase; + nsCOMPtr<nsIFile> dbPath; + nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) + { + /* Get the profile directory */ + rv = abManager->GetUserProfileDirectory(getter_AddRefs(dbPath)); + if (NS_SUCCEEDED(rv)) + { + // Create a new address book file - we don't care what the file + // name is, as long as it's unique + rv = dbPath->Append(NS_LITERAL_STRING("impab.mab")); + if (NS_SUCCEEDED(rv)) + { + rv = dbPath->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600); + + if (NS_SUCCEEDED(rv)) + { + IMPORT_LOG0("Getting the address database factory\n"); + + nsCOMPtr<nsIAddrDatabase> addrDBFactory = + do_GetService(NS_ADDRDATABASE_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return nullptr; + + IMPORT_LOG0("Opening the new address book\n"); + rv = addrDBFactory->Open(dbPath, true, true, + getter_AddRefs(pDatabase)); + } + } + } + } + if (NS_FAILED(rv)) + { + IMPORT_LOG0("Failed to get the user profile directory from the address book session\n"); + } + + if (pDatabase && dbPath) + { + // We made a database, add it to the UI?!?!?!?!?!?! + // This is major bogosity again! Why doesn't the address book + // just handle this properly for me? Uggggg... + + nsCOMPtr<nsIAbDirectory> parentDir; + abManager->GetDirectory(NS_LITERAL_CSTRING(kAllDirectoryRoot), + getter_AddRefs(parentDir)); + if (parentDir) + { + nsAutoCString URI("moz-abmdbdirectory://"); + nsAutoCString leafName; + rv = dbPath->GetNativeLeafName(leafName); + if (NS_FAILED(rv)) + IMPORT_LOG0("*** Error: Unable to get name of database file\n"); + else + { + URI.Append(leafName); + rv = parentDir->CreateDirectoryByURI(nsDependentString(name), URI); + if (NS_FAILED(rv)) + IMPORT_LOG0("*** Error: Unable to create address book directory\n"); + } + } + + if (NS_SUCCEEDED(rv)) + IMPORT_LOG0("Added new address book to the UI\n"); + else + IMPORT_LOG0("*** Error: An error occurred while adding the address book to the UI\n"); + } + + return pDatabase.forget(); +} + +NS_IMETHODIMP nsImportGenericAddressBooks::BeginImport(nsISupportsString *successLog, nsISupportsString *errorLog, bool *_retval) +{ + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!_retval) + return NS_ERROR_NULL_POINTER; + + nsString success; + nsString error; + + if (!m_doImport) { + *_retval = true; + nsImportStringBundle::GetStringByID(IMPORT_NO_ADDRBOOKS, m_stringBundle, + success); + SetLogs(success, error, successLog, errorLog); + return NS_OK; + } + + if (!m_pInterface || !m_Books) { + nsImportStringBundle::GetStringByID(IMPORT_ERROR_AB_NOTINITIALIZED, + m_stringBundle, error); + SetLogs(success, error, successLog, errorLog); + *_retval = false; + return NS_OK; + } + + bool needsFieldMap = false; + + if (NS_FAILED(m_pInterface->GetNeedsFieldMap(m_pLocation, &needsFieldMap)) || + (needsFieldMap && !m_pFieldMap)) { + nsImportStringBundle::GetStringByID(IMPORT_ERROR_AB_NOTINITIALIZED, + m_stringBundle, error); + SetLogs(success, error, successLog, errorLog); + *_retval = false; + return NS_OK; + } + + NS_IF_RELEASE(m_pSuccessLog); + NS_IF_RELEASE(m_pErrorLog); + m_pSuccessLog = successLog; + m_pErrorLog = errorLog; + NS_IF_ADDREF(m_pSuccessLog); + NS_IF_ADDREF(m_pErrorLog); + + + // create the info need to drive address book import. We're + // not going to create a new thread for this since address books + // don't tend to be large, and import is rare. + m_pThreadData = new AddressThreadData(); + m_pThreadData->books = m_Books; + NS_ADDREF(m_Books); + m_pThreadData->addressImport = m_pInterface; + NS_ADDREF(m_pInterface); + m_pThreadData->fieldMap = m_pFieldMap; + NS_IF_ADDREF(m_pFieldMap); + m_pThreadData->errorLog = m_pErrorLog; + NS_IF_ADDREF(m_pErrorLog); + m_pThreadData->successLog = m_pSuccessLog; + NS_IF_ADDREF(m_pSuccessLog); + if (m_pDestinationUri) + m_pThreadData->pDestinationUri = strdup(m_pDestinationUri); + + uint32_t count = 0; + m_Books->GetLength(&count); + // Create/obtain any address books that we need here, so that we don't need + // to do so inside the import thread which would just proxy the create + // operations back to the main thread anyway. + nsCOMPtr<nsIAddrDatabase> db = GetAddressBookFromUri(m_pDestinationUri); + for (uint32_t i = 0; i < count; ++i) + { + nsCOMPtr<nsIImportABDescriptor> book = do_QueryElementAt(m_Books, i); + if (book) + { + if (!db) + { + nsString name; + book->GetPreferredName(name); + db = GetAddressBook(name.get(), true); + } + m_DBs.AppendObject(db); + } + } + m_pThreadData->dBs = &m_DBs; + + NS_IF_ADDREF(m_pThreadData->stringBundle = m_stringBundle); + + nsresult rv; + m_pThreadData->ldifService = do_GetService(NS_ABLDIFSERVICE_CONTRACTID, &rv); + + ImportAddressThread(m_pThreadData); + delete m_pThreadData; + m_pThreadData = nullptr; + *_retval = true; + + return NS_OK; +} + +NS_IMETHODIMP nsImportGenericAddressBooks::ContinueImport(bool *_retval) +{ + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!_retval) + return NS_ERROR_NULL_POINTER; + + *_retval = true; + if (m_pThreadData) { + if (m_pThreadData->fatalError) + *_retval = false; + } + + return NS_OK; +} + + +NS_IMETHODIMP nsImportGenericAddressBooks::GetProgress(int32_t *_retval) +{ + // This returns the progress from the the currently + // running import mail or import address book thread. + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!_retval) + return NS_ERROR_NULL_POINTER; + + if (!m_pThreadData || !(m_pThreadData->threadAlive)) { + *_retval = 100; + return NS_OK; + } + + uint32_t sz = 0; + if (m_pThreadData->currentSize && m_pInterface) { + if (NS_FAILED(m_pInterface->GetImportProgress(&sz))) + sz = 0; + } + + if (m_totalSize) + *_retval = ((m_pThreadData->currentTotal + sz) * 100) / m_totalSize; + else + *_retval = 0; + + // never return less than 5 so it looks like we are doing something! + if (*_retval < 5) + *_retval = 5; + + // as long as the thread is alive don't return completely + // done. + if (*_retval > 99) + *_retval = 99; + + return NS_OK; +} + + +NS_IMETHODIMP nsImportGenericAddressBooks::CancelImport(void) +{ + if (m_pThreadData) { + m_pThreadData->abort = true; + m_pThreadData = nullptr; + } + + return NS_OK; +} + + +AddressThreadData::AddressThreadData() +{ + fatalError = false; + driverAlive = true; + threadAlive = true; + abort = false; + currentTotal = 0; + currentSize = 0; + books = nullptr; + addressImport = nullptr; + successLog = nullptr; + errorLog = nullptr; + pDestinationUri = nullptr; + fieldMap = nullptr; + stringBundle = nullptr; + ldifService = nullptr; +} + +AddressThreadData::~AddressThreadData() +{ + if (pDestinationUri) + NS_Free(pDestinationUri); + + NS_IF_RELEASE(books); + NS_IF_RELEASE(addressImport); + NS_IF_RELEASE(errorLog); + NS_IF_RELEASE(successLog); + NS_IF_RELEASE(fieldMap); + NS_IF_RELEASE(stringBundle); +} + +void nsImportGenericAddressBooks::ReportError(const char16_t *pName, + nsString *pStream, + nsIStringBundle* aBundle) +{ + if (!pStream) + return; + // load the error string + char16_t *pFmt = nsImportStringBundle::GetStringByID(IMPORT_ERROR_GETABOOK, aBundle); + char16_t *pText = nsTextFormatter::smprintf(pFmt, pName); + pStream->Append(pText); + nsTextFormatter::smprintf_free(pText); + NS_Free(pFmt); + pStream->AppendLiteral(MSG_LINEBREAK); +} + +static void ImportAddressThread(void *stuff) +{ + IMPORT_LOG0("In Begin ImportAddressThread\n"); + + AddressThreadData *pData = (AddressThreadData *)stuff; + uint32_t count = 0; + uint32_t i; + bool import; + uint32_t size; + + nsString success; + nsString error; + + (void) pData->books->GetLength(&count); + + for (i = 0; (i < count) && !(pData->abort); i++) { + nsCOMPtr<nsIImportABDescriptor> book = + do_QueryElementAt(pData->books, i); + + if (book) { + import = false; + size = 0; + nsresult rv = book->GetImport(&import); + if (NS_SUCCEEDED(rv) && import) + rv = book->GetSize(&size); + + if (NS_SUCCEEDED(rv) && size && import) { + nsString name; + book->GetPreferredName(name); + + nsCOMPtr<nsIAddrDatabase> db = pData->dBs->ObjectAt(i); + + bool fatalError = false; + pData->currentSize = size; + if (db) { + char16_t *pSuccess = nullptr; + char16_t *pError = nullptr; + + /* + if (pData->fieldMap) { + int32_t sz = 0; + int32_t mapIndex; + bool active; + pData->fieldMap->GetMapSize(&sz); + IMPORT_LOG1("**** Field Map Size: %d\n", (int) sz); + for (int32_t i = 0; i < sz; i++) { + pData->fieldMap->GetFieldMap(i, &mapIndex); + pData->fieldMap->GetFieldActive(i, &active); + IMPORT_LOG3("Field map #%d: index=%d, active=%d\n", (int) i, (int) mapIndex, (int) active); + } + } + */ + + rv = pData->addressImport->ImportAddressBook(book, + db, + pData->fieldMap, + pData->ldifService, + &pError, + &pSuccess, + &fatalError); + if (NS_SUCCEEDED(rv) && pSuccess) { + success.Append(pSuccess); + NS_Free(pSuccess); + } + if (pError) { + error.Append(pError); + NS_Free(pError); + } + } + else { + nsImportGenericAddressBooks::ReportError(name.get(), &error, pData->stringBundle); + } + + pData->currentSize = 0; + pData->currentTotal += size; + + if (db) + db->Close(true); + + if (fatalError) { + pData->fatalError = true; + break; + } + } + } + } + + + nsImportGenericAddressBooks::SetLogs(success, error, pData->successLog, pData->errorLog); + + if (pData->abort || pData->fatalError) { + // FIXME: do what is necessary to get rid of what has been imported so far. + // Nothing if we went into an existing address book! Otherwise, delete + // the ones we created? + } + +} |