diff options
Diffstat (limited to 'mailnews/import/outlook/src/nsOutlookImport.cpp')
-rw-r--r-- | mailnews/import/outlook/src/nsOutlookImport.cpp | 589 |
1 files changed, 589 insertions, 0 deletions
diff --git a/mailnews/import/outlook/src/nsOutlookImport.cpp b/mailnews/import/outlook/src/nsOutlookImport.cpp new file mode 100644 index 000000000..eaaf24fc3 --- /dev/null +++ b/mailnews/import/outlook/src/nsOutlookImport.cpp @@ -0,0 +1,589 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* + Outlook Express (Win32) import mail and addressbook interfaces +*/ +#include "nscore.h" +#include "nsStringGlue.h" +#include "nsMsgUtils.h" +#include "nsIServiceManager.h" +#include "nsIImportService.h" +#include "nsIComponentManager.h" +#include "nsOutlookImport.h" +#include "nsIMemory.h" +#include "nsIImportService.h" +#include "nsIImportMail.h" +#include "nsIImportMailboxDescriptor.h" +#include "nsIImportGeneric.h" +#include "nsIImportAddressBooks.h" +#include "nsIImportABDescriptor.h" +#include "nsIImportFieldMap.h" +#include "nsXPCOM.h" +#include "nsISupportsPrimitives.h" +#include "nsIOutputStream.h" +#include "nsIAddrDatabase.h" +#include "nsOutlookSettings.h" +#include "nsTextFormatter.h" +#include "nsOutlookStringBundle.h" +#include "nsIStringBundle.h" +#include "OutlookDebugLog.h" +#include "nsUnicharUtils.h" + +#include "nsOutlookMail.h" + +#include "MapiApi.h" + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +PRLogModuleInfo *OUTLOOKLOGMODULE = nullptr; + +class ImportOutlookMailImpl : public nsIImportMail +{ +public: + ImportOutlookMailImpl(); + + static nsresult Create(nsIImportMail** aImport); + + // nsISupports interface + NS_DECL_THREADSAFE_ISUPPORTS + + // nsIImportmail interface + + /* void GetDefaultLocation (out nsIFile location, out boolean found, out boolean userVerify); */ + NS_IMETHOD GetDefaultLocation(nsIFile **location, bool *found, bool *userVerify); + + /* nsIArray FindMailboxes (in nsIFile location); */ + NS_IMETHOD FindMailboxes(nsIFile *location, nsIArray **_retval); + + NS_IMETHOD ImportMailbox(nsIImportMailboxDescriptor *source, + nsIMsgFolder *dstFolder, + char16_t **pErrorLog, char16_t **pSuccessLog, + bool *fatalError); + + /* unsigned long GetImportProgress (); */ + NS_IMETHOD GetImportProgress(uint32_t *_retval); + + NS_IMETHOD TranslateFolderName(const nsAString & aFolderName, nsAString & _retval); + +public: + static void ReportSuccess(nsString& name, int32_t count, nsString *pStream); + static void ReportError(int32_t errorNum, nsString& name, nsString *pStream); + static void AddLinebreak(nsString *pStream); + static void SetLogs(nsString& success, nsString& error, char16_t **pError, char16_t **pSuccess); + +private: + virtual ~ImportOutlookMailImpl(); + nsOutlookMail m_mail; + uint32_t m_bytesDone; +}; + + +class ImportOutlookAddressImpl : public nsIImportAddressBooks +{ +public: + ImportOutlookAddressImpl(); + + static nsresult Create(nsIImportAddressBooks** aImport); + + // nsISupports interface + NS_DECL_THREADSAFE_ISUPPORTS + + // nsIImportAddressBooks interface + + NS_IMETHOD GetSupportsMultiple(bool *_retval) { *_retval = true; return NS_OK;} + + NS_IMETHOD GetAutoFind(char16_t **description, bool *_retval); + + NS_IMETHOD GetNeedsFieldMap(nsIFile *location, bool *_retval) { *_retval = false; return NS_OK;} + + NS_IMETHOD GetDefaultLocation(nsIFile **location, bool *found, bool *userVerify) + { return NS_ERROR_FAILURE;} + + NS_IMETHOD FindAddressBooks(nsIFile *location, nsIArray **_retval); + + NS_IMETHOD InitFieldMap(nsIImportFieldMap *fieldMap) + { return NS_ERROR_FAILURE; } + + NS_IMETHOD ImportAddressBook(nsIImportABDescriptor *source, + nsIAddrDatabase *destination, + nsIImportFieldMap *fieldMap, + nsISupports *aSupportService, + char16_t **errorLog, + char16_t **successLog, + bool *fatalError); + + NS_IMETHOD GetImportProgress(uint32_t *_retval); + + NS_IMETHOD GetSampleData(int32_t index, bool *pFound, char16_t **pStr) + { return NS_ERROR_FAILURE;} + + NS_IMETHOD SetSampleLocation(nsIFile *) { return NS_OK; } + +private: + virtual ~ImportOutlookAddressImpl(); + void ReportSuccess(nsString& name, nsString *pStream); + +private: + uint32_t m_msgCount; + uint32_t m_msgTotal; + nsOutlookMail m_address; +}; +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// + + +nsOutlookImport::nsOutlookImport() +{ + // Init logging module. + if (!OUTLOOKLOGMODULE) + OUTLOOKLOGMODULE = PR_NewLogModule("IMPORT"); + + IMPORT_LOG0("nsOutlookImport Module Created\n"); + + nsOutlookStringBundle::GetStringBundle(); +} + + +nsOutlookImport::~nsOutlookImport() +{ + IMPORT_LOG0("nsOutlookImport Module Deleted\n"); +} + +NS_IMPL_ISUPPORTS(nsOutlookImport, nsIImportModule) + +NS_IMETHODIMP nsOutlookImport::GetName(char16_t **name) +{ + NS_PRECONDITION(name != nullptr, "null ptr"); + if (! name) + return NS_ERROR_NULL_POINTER; + + *name = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_NAME); + return NS_OK; +} + +NS_IMETHODIMP nsOutlookImport::GetDescription(char16_t **name) +{ + NS_PRECONDITION(name != nullptr, "null ptr"); + if (!name) + return NS_ERROR_NULL_POINTER; + + *name = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_DESCRIPTION); + + return NS_OK; +} + +NS_IMETHODIMP nsOutlookImport::GetSupports(char **supports) +{ + NS_PRECONDITION(supports != nullptr, "null ptr"); + if (! supports) + return NS_ERROR_NULL_POINTER; + + *supports = strdup(kOutlookSupportsString); + return NS_OK; +} + +NS_IMETHODIMP nsOutlookImport::GetSupportsUpgrade(bool *pUpgrade) +{ + NS_PRECONDITION(pUpgrade != nullptr, "null ptr"); + if (! pUpgrade) + return NS_ERROR_NULL_POINTER; + + *pUpgrade = true; + return NS_OK; +} + +NS_IMETHODIMP nsOutlookImport::GetImportInterface(const char *pImportType, nsISupports **ppInterface) +{ + NS_PRECONDITION(pImportType != nullptr, "null ptr"); + if (! pImportType) + return NS_ERROR_NULL_POINTER; + NS_PRECONDITION(ppInterface != nullptr, "null ptr"); + if (! ppInterface) + return NS_ERROR_NULL_POINTER; + + *ppInterface = nullptr; + nsresult rv; + if (!strcmp(pImportType, "mail")) { + // create the nsIImportMail interface and return it! + nsIImportMail * pMail = nullptr; + nsIImportGeneric *pGeneric = nullptr; + rv = ImportOutlookMailImpl::Create(&pMail); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv)) { + rv = impSvc->CreateNewGenericMail(&pGeneric); + if (NS_SUCCEEDED(rv)) { + pGeneric->SetData("mailInterface", pMail); + nsString name; + nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_NAME, name); + nsCOMPtr<nsISupportsString> nameString (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv)) { + nameString->SetData(name); + pGeneric->SetData("name", nameString); + rv = pGeneric->QueryInterface(kISupportsIID, (void **)ppInterface); + } + } + } + } + NS_IF_RELEASE(pMail); + NS_IF_RELEASE(pGeneric); + return rv; + } + + if (!strcmp(pImportType, "addressbook")) { + // create the nsIImportAddressBook interface and return it! + nsIImportAddressBooks * pAddress = nullptr; + nsIImportGeneric * pGeneric = nullptr; + rv = ImportOutlookAddressImpl::Create(&pAddress); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIImportService> impSvc(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv)) { + rv = impSvc->CreateNewGenericAddressBooks(&pGeneric); + if (NS_SUCCEEDED(rv)) { + pGeneric->SetData("addressInterface", pAddress); + rv = pGeneric->QueryInterface(kISupportsIID, (void **)ppInterface); + } + } + } + NS_IF_RELEASE(pAddress); + NS_IF_RELEASE(pGeneric); + return rv; + } + + if (!strcmp(pImportType, "settings")) { + nsIImportSettings *pSettings = nullptr; + rv = nsOutlookSettings::Create(&pSettings); + if (NS_SUCCEEDED(rv)) + pSettings->QueryInterface(kISupportsIID, (void **)ppInterface); + NS_IF_RELEASE(pSettings); + return rv; + } + + return NS_ERROR_NOT_AVAILABLE; +} + +///////////////////////////////////////////////////////////////////////////////// +nsresult ImportOutlookMailImpl::Create(nsIImportMail** aImport) +{ + NS_PRECONDITION(aImport != nullptr, "null ptr"); + if (! aImport) + return NS_ERROR_NULL_POINTER; + + *aImport = new ImportOutlookMailImpl(); + if (! *aImport) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aImport); + return NS_OK; +} + +ImportOutlookMailImpl::ImportOutlookMailImpl() +{ + nsOutlookCompose::CreateIdentity(); +} + +ImportOutlookMailImpl::~ImportOutlookMailImpl() +{ + nsOutlookCompose::ReleaseIdentity(); +} + +NS_IMPL_ISUPPORTS(ImportOutlookMailImpl, nsIImportMail) + +NS_IMETHODIMP ImportOutlookMailImpl::GetDefaultLocation(nsIFile **ppLoc, bool *found, bool *userVerify) +{ + NS_PRECONDITION(ppLoc != nullptr, "null ptr"); + NS_PRECONDITION(found != nullptr, "null ptr"); + NS_PRECONDITION(userVerify != nullptr, "null ptr"); + if (!ppLoc || !found || !userVerify) + return NS_ERROR_NULL_POINTER; + + *found = false; + *ppLoc = nullptr; + *userVerify = false; + // We need to verify here that we can get the mail, if true then + // return a dummy location, otherwise return no location + CMapiApi mapi; + if (!mapi.Initialize()) + return NS_OK; + if (!mapi.LogOn()) + return NS_OK; + + CMapiFolderList store; + if (!mapi.IterateStores(store)) + return NS_OK; + + if (store.GetSize() == 0) + return NS_OK; + + + nsresult rv; + nsCOMPtr <nsIFile> resultFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return rv; + + *found = true; + NS_IF_ADDREF(*ppLoc = resultFile); + *userVerify = false; + + return NS_OK; +} + + +NS_IMETHODIMP ImportOutlookMailImpl::FindMailboxes(nsIFile *pLoc, nsIArray **ppArray) +{ + NS_PRECONDITION(pLoc != nullptr, "null ptr"); + NS_PRECONDITION(ppArray != nullptr, "null ptr"); + if (!pLoc || !ppArray) + return NS_ERROR_NULL_POINTER; + return m_mail.GetMailFolders(ppArray); +} + +void ImportOutlookMailImpl::AddLinebreak(nsString *pStream) +{ + if (pStream) + pStream->Append(char16_t('\n')); +} + +void ImportOutlookMailImpl::ReportSuccess(nsString& name, int32_t count, nsString *pStream) +{ + if (!pStream) + return; + // load the success string + char16_t *pFmt = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_MAILBOX_SUCCESS); + char16_t *pText = nsTextFormatter::smprintf(pFmt, name.get(), count); + pStream->Append(pText); + nsTextFormatter::smprintf_free(pText); + nsOutlookStringBundle::FreeString(pFmt); + AddLinebreak(pStream); +} + +void ImportOutlookMailImpl::ReportError(int32_t errorNum, nsString& name, nsString *pStream) +{ + if (!pStream) + return; + // load the error string + char16_t *pFmt = nsOutlookStringBundle::GetStringByID(errorNum); + char16_t *pText = nsTextFormatter::smprintf(pFmt, name.get()); + pStream->Append(pText); + nsTextFormatter::smprintf_free(pText); + nsOutlookStringBundle::FreeString(pFmt); + AddLinebreak(pStream); +} + + +void ImportOutlookMailImpl::SetLogs(nsString& success, nsString& error, char16_t **pError, char16_t **pSuccess) +{ + if (pError) + *pError = ToNewUnicode(error); + if (pSuccess) + *pSuccess = ToNewUnicode(success); +} + +NS_IMETHODIMP +ImportOutlookMailImpl::ImportMailbox(nsIImportMailboxDescriptor *pSource, + nsIMsgFolder *dstFolder, + char16_t **pErrorLog, + char16_t **pSuccessLog, + bool *fatalError) +{ + NS_ENSURE_ARG_POINTER(pSource); + NS_ENSURE_ARG_POINTER(dstFolder); + NS_ENSURE_ARG_POINTER(fatalError); + + nsString success; + nsString error; + bool abort = false; + nsString name; + char16_t *pName; + if (NS_SUCCEEDED( pSource->GetDisplayName( &pName))) { + name = pName; + NS_Free( pName); + } + + uint32_t mailSize = 0; + pSource->GetSize(&mailSize); + if (mailSize == 0) { + ReportSuccess(name, 0, &success); + SetLogs(success, error, pErrorLog, pSuccessLog); + return NS_OK; + } + + uint32_t index = 0; + pSource->GetIdentifier(&index); + int32_t msgCount = 0; + nsresult rv = NS_OK; + + m_bytesDone = 0; + + rv = m_mail.ImportMailbox(&m_bytesDone, &abort, (int32_t)index, name.get(), + dstFolder, &msgCount); + + if (NS_SUCCEEDED(rv)) + ReportSuccess(name, msgCount, &success); + else + ReportError(OUTLOOKIMPORT_MAILBOX_CONVERTERROR, name, &error); + + SetLogs(success, error, pErrorLog, pSuccessLog); + + return rv; +} + + +NS_IMETHODIMP ImportOutlookMailImpl::GetImportProgress(uint32_t *pDoneSoFar) +{ + NS_PRECONDITION(pDoneSoFar != nullptr, "null ptr"); + if (! pDoneSoFar) + return NS_ERROR_NULL_POINTER; + + *pDoneSoFar = m_bytesDone; + return NS_OK; +} + +NS_IMETHODIMP ImportOutlookMailImpl::TranslateFolderName(const nsAString & aFolderName, nsAString & _retval) +{ + if (aFolderName.LowerCaseEqualsLiteral("deleted items")) + _retval = NS_LITERAL_STRING(kDestTrashFolderName); + else if (aFolderName.LowerCaseEqualsLiteral("sent items")) + _retval = NS_LITERAL_STRING(kDestSentFolderName); + else if (aFolderName.LowerCaseEqualsLiteral("outbox")) + _retval = NS_LITERAL_STRING(kDestUnsentMessagesFolderName); + else + _retval = aFolderName; + return NS_OK; +} + +nsresult ImportOutlookAddressImpl::Create(nsIImportAddressBooks** aImport) +{ + NS_PRECONDITION(aImport != nullptr, "null ptr"); + if (! aImport) + return NS_ERROR_NULL_POINTER; + + *aImport = new ImportOutlookAddressImpl(); + if (! *aImport) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aImport); + return NS_OK; +} + +ImportOutlookAddressImpl::ImportOutlookAddressImpl() +{ + m_msgCount = 0; + m_msgTotal = 0; +} + +ImportOutlookAddressImpl::~ImportOutlookAddressImpl() +{ +} + +NS_IMPL_ISUPPORTS(ImportOutlookAddressImpl, nsIImportAddressBooks) + +NS_IMETHODIMP ImportOutlookAddressImpl::GetAutoFind(char16_t **description, bool *_retval) +{ + NS_PRECONDITION(description != nullptr, "null ptr"); + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (! description || !_retval) + return NS_ERROR_NULL_POINTER; + + *_retval = true; + nsString str; + nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_ADDRNAME, str); + *description = ToNewUnicode(str); + return NS_OK; +} + +NS_IMETHODIMP ImportOutlookAddressImpl::FindAddressBooks(nsIFile *location, nsIArray **_retval) +{ + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!_retval) + return NS_ERROR_NULL_POINTER; + + return m_address.GetAddressBooks(_retval); +} + +NS_IMETHODIMP ImportOutlookAddressImpl::ImportAddressBook(nsIImportABDescriptor *source, + nsIAddrDatabase *destination, + nsIImportFieldMap *fieldMap, + nsISupports *aSupportService, + char16_t **pErrorLog, + char16_t **pSuccessLog, + bool *fatalError) +{ + m_msgCount = 0; + m_msgTotal = 0; + NS_PRECONDITION(source != nullptr, "null ptr"); + NS_PRECONDITION(destination != nullptr, "null ptr"); + NS_PRECONDITION(fatalError != nullptr, "null ptr"); + + nsString success; + nsString error; + if (!source || !destination || !fatalError) { + IMPORT_LOG0("*** Bad param passed to outlook address import\n"); + nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_ADDRESS_BADPARAM, error); + if (fatalError) + *fatalError = true; + ImportOutlookMailImpl::SetLogs(success, error, pErrorLog, pSuccessLog); + return NS_ERROR_NULL_POINTER; + } + + nsString name; + source->GetPreferredName(name); + + uint32_t id; + if (NS_FAILED(source->GetIdentifier(&id))) { + ImportOutlookMailImpl::ReportError(OUTLOOKIMPORT_ADDRESS_BADSOURCEFILE, name, &error); + ImportOutlookMailImpl::SetLogs(success, error, pErrorLog, pSuccessLog); + return NS_ERROR_FAILURE; + } + + nsresult rv = NS_OK; + rv = m_address.ImportAddresses(&m_msgCount, &m_msgTotal, name.get(), id, destination, error); + if (NS_SUCCEEDED(rv) && error.IsEmpty()) + ReportSuccess(name, &success); + else + ImportOutlookMailImpl::ReportError(OUTLOOKIMPORT_ADDRESS_CONVERTERROR, name, &error); + + ImportOutlookMailImpl::SetLogs(success, error, pErrorLog, pSuccessLog); + IMPORT_LOG0("*** Returning from outlook address import\n"); + return destination->Commit(nsAddrDBCommitType::kLargeCommit); +} + + +NS_IMETHODIMP ImportOutlookAddressImpl::GetImportProgress(uint32_t *_retval) +{ + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!_retval) + return NS_ERROR_NULL_POINTER; + + uint32_t result = m_msgCount; + if (m_msgTotal) { + result *= 100; + result /= m_msgTotal; + } + else + result = 0; + + if (result > 100) + result = 100; + + *_retval = result; + + return NS_OK; +} + +void ImportOutlookAddressImpl::ReportSuccess(nsString& name, nsString *pStream) +{ + if (!pStream) + return; + // load the success string + char16_t *pFmt = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_ADDRESS_SUCCESS); + char16_t *pText = nsTextFormatter::smprintf(pFmt, name.get()); + pStream->Append(pText); + nsTextFormatter::smprintf_free(pText); + nsOutlookStringBundle::FreeString(pFmt); + ImportOutlookMailImpl::AddLinebreak(pStream); +} |