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; }
static void ImportAddressThread( void *stuff) { IMPORT_LOG0( "In Begin ImportAddressThread\n"); AddressThreadData *pData = (AddressThreadData *)stuff; PRUint32 count = 0; nsresult rv = pData->books->Count( &count); PRUint32 i; PRBool import; PRUint32 size; nsCOMPtr<nsIAddrDatabase> destDB( getter_AddRefs( GetAddressBookFromUri( pData->pDestinationUri))); nsCOMPtr<nsIAddrDatabase> pDestDB; nsString success; nsString error; nsCOMPtr<nsIStringBundle> pBundle; rv = nsImportStringBundle::GetStringBundleProxy(pData->stringBundle, getter_AddRefs(pBundle)); if (NS_FAILED(rv)) { IMPORT_LOG0("*** ImportMailThread: Unable to obtain proxy string service for the import."); pData->abort = PR_TRUE; } for (i = 0; (i < count) && !(pData->abort); i++) { nsCOMPtr<nsIImportABDescriptor> book = do_QueryElementAt(pData->books, i); if (book) { import = PR_FALSE; size = 0; rv = book->GetImport( &import); if (import) rv = book->GetSize( &size); if (size && import) { nsString name; book->GetPreferredName(name); if (destDB) { pDestDB = destDB; } else { pDestDB = GetAddressBook(name.get(), PR_TRUE); } nsCOMPtr<nsIProxyObjectManager> proxyObjectManager = do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv); if (NS_FAILED(rv)) return; nsCOMPtr<nsIAddrDatabase> proxyAddrDatabase; rv = proxyObjectManager->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIAddrDatabase), pDestDB, NS_PROXY_SYNC | NS_PROXY_ALWAYS, getter_AddRefs(proxyAddrDatabase)); if (NS_FAILED(rv)) return; PRBool fatalError = PR_FALSE; pData->currentSize = size; if (proxyAddrDatabase) { PRUnichar *pSuccess = nsnull; PRUnichar *pError = nsnull; /* if (pData->fieldMap) { PRInt32 sz = 0; PRInt32 mapIndex; PRBool active; pData->fieldMap->GetMapSize( &sz); IMPORT_LOG1( "**** Field Map Size: %d\n", (int) sz); for (PRInt32 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, proxyAddrDatabase, pData->fieldMap, pData->ldifService, pData->bAddrLocInput, &pError, &pSuccess, &fatalError); if (pSuccess) { success.Append( pSuccess); NS_Free( pSuccess); } if (pError) { error.Append( pError); NS_Free( pError); } } else { nsImportGenericAddressBooks::ReportError(name.get(), &error, pBundle); } pData->currentSize = 0; pData->currentTotal += size; if (!proxyAddrDatabase) { proxyAddrDatabase->Close( PR_TRUE); } if (fatalError) { pData->fatalError = PR_TRUE; break; } } } if (destDB) { destDB->Close( PR_TRUE); } } 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? } pData->ThreadDelete(); }