summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/addrbook/src/nsAbDirProperty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/addrbook/src/nsAbDirProperty.cpp')
-rw-r--r--comm/mailnews/addrbook/src/nsAbDirProperty.cpp573
1 files changed, 573 insertions, 0 deletions
diff --git a/comm/mailnews/addrbook/src/nsAbDirProperty.cpp b/comm/mailnews/addrbook/src/nsAbDirProperty.cpp
new file mode 100644
index 0000000000..67860e424d
--- /dev/null
+++ b/comm/mailnews/addrbook/src/nsAbDirProperty.cpp
@@ -0,0 +1,573 @@
+/* -*- 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 "nsAbDirProperty.h"
+#include "nsIAbCard.h"
+#include "nsIPrefService.h"
+#include "nsIPrefLocalizedString.h"
+#include "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "prmem.h"
+#include "nsIAbManager.h"
+#include "nsArrayUtils.h"
+#include "nsIUUIDGenerator.h"
+#include "mozilla/Components.h"
+#include "mozilla/Services.h"
+#include "nsIObserverService.h"
+#include "mozilla/dom/Promise.h"
+
+using mozilla::ErrorResult;
+using mozilla::dom::Promise;
+using namespace mozilla;
+
+// From nsDirPrefs
+#define kDefaultPosition 1
+
+nsAbDirProperty::nsAbDirProperty(void)
+ : m_LastModifiedDate(0), mIsValidURI(false) {
+ m_IsMailList = false;
+ mUID = EmptyCString();
+}
+
+nsAbDirProperty::~nsAbDirProperty(void) {
+#if 0
+ // this code causes a regression #138647
+ // don't turn it on until you figure it out
+ if (m_AddressList) {
+ uint32_t count;
+ nsresult rv;
+ rv = m_AddressList->GetLength(&count);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
+ int32_t i;
+ for (i = count - 1; i >= 0; i--)
+ m_AddressList->RemoveElementAt(i);
+ }
+#endif
+}
+
+NS_IMPL_ISUPPORTS(nsAbDirProperty, nsIAbDirectory, nsISupportsWeakReference)
+
+NS_IMETHODIMP nsAbDirProperty::GetPropertiesChromeURI(nsACString& aResult) {
+ aResult.AssignLiteral(
+ "chrome://messenger/content/addressbook/abAddressBookNameDialog.xhtml");
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetDirName(nsAString& aDirName) {
+ if (m_DirPrefId.IsEmpty()) {
+ aDirName = m_ListDirName;
+ return NS_OK;
+ }
+
+ nsCString dirName;
+ nsresult rv = GetLocalizedStringValue("description", EmptyCString(), dirName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // In TB 2 only some prefs had chrome:// URIs. We had code in place that would
+ // only get the localized string pref for the particular address books that
+ // were built-in.
+ // Additionally, nsIPrefBranch::getComplexValue will only get a non-user-set,
+ // non-locked pref value if it is a chrome:// URI and will get the string
+ // value at that chrome URI. This breaks extensions/autoconfig that want to
+ // set default pref values and allow users to change directory names.
+ //
+ // Now we have to support this, and so if for whatever reason we fail to get
+ // the localized version, then we try and get the non-localized version
+ // instead. If the string value is empty, then we'll just get the empty value
+ // back here.
+ if (dirName.IsEmpty()) {
+ rv = GetStringValue("description", EmptyCString(), dirName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ CopyUTF8toUTF16(dirName, aDirName);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetDirName(const nsAString& aDirName) {
+ if (m_DirPrefId.IsEmpty()) {
+ m_ListDirName = aDirName;
+ return NS_OK;
+ }
+
+ // Store the old value.
+ nsString oldDirName;
+ nsresult rv = GetDirName(oldDirName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Save the new value
+ rv = SetLocalizedStringValue("description", NS_ConvertUTF16toUTF8(aDirName));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIAbManager> abManager =
+ do_GetService("@mozilla.org/abmanager;1", &rv);
+
+ if (NS_SUCCEEDED(rv)) {
+ nsCOMPtr<nsIObserverService> observerService =
+ mozilla::services::GetObserverService();
+ // We inherit from nsIAbDirectory, so this static cast should be safe.
+ observerService->NotifyObservers(static_cast<nsIAbDirectory*>(this),
+ "addrbook-directory-updated", u"DirName");
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetDirType(int32_t* aDirType) {
+ return GetIntValue("dirType", nsIAbManager::LDAP_DIRECTORY_TYPE, aDirType);
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetFileName(nsACString& aFileName) {
+ return GetStringValue("filename", EmptyCString(), aFileName);
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetUID(nsACString& aUID) {
+ nsresult rv = NS_OK;
+ if (!mUID.IsEmpty()) {
+ aUID = mUID;
+ return rv;
+ }
+ if (!m_IsMailList) {
+ rv = GetStringValue("uid", EmptyCString(), aUID);
+ if (!aUID.IsEmpty()) {
+ return rv;
+ }
+ }
+
+ nsCOMPtr<nsIUUIDGenerator> uuidgen =
+ mozilla::components::UUIDGenerator::Service();
+ NS_ENSURE_TRUE(uuidgen, NS_ERROR_FAILURE);
+
+ nsID id;
+ rv = uuidgen->GenerateUUIDInPlace(&id);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ char idString[NSID_LENGTH];
+ id.ToProvidedString(idString);
+
+ aUID.AppendASCII(idString + 1, NSID_LENGTH - 3);
+ return SetUID(aUID);
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetUID(const nsACString& aUID) {
+ mUID = aUID;
+ if (m_IsMailList) {
+ return NS_OK;
+ }
+ return SetStringValue("uid", aUID);
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetURI(nsACString& aURI) {
+ // XXX Should we complete this for Mailing Lists?
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetPosition(int32_t* aPosition) {
+ return GetIntValue("position", kDefaultPosition, aPosition);
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetLastModifiedDate(
+ uint32_t* aLastModifiedDate) {
+ NS_ENSURE_ARG_POINTER(aLastModifiedDate);
+ *aLastModifiedDate = m_LastModifiedDate;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetLastModifiedDate(uint32_t aLastModifiedDate) {
+ if (aLastModifiedDate) {
+ m_LastModifiedDate = aLastModifiedDate;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetListNickName(nsAString& aListNickName) {
+ aListNickName = m_ListNickName;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetListNickName(const nsAString& aListNickName) {
+ m_ListNickName = aListNickName;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetDescription(nsAString& aDescription) {
+ aDescription = m_Description;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetDescription(const nsAString& aDescription) {
+ m_Description = aDescription;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetIsMailList(bool* aIsMailList) {
+ *aIsMailList = m_IsMailList;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetIsMailList(bool aIsMailList) {
+ m_IsMailList = aIsMailList;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::CopyMailList(nsIAbDirectory* srcList) {
+ SetIsMailList(true);
+
+ nsString str;
+ srcList->GetDirName(str);
+ SetDirName(str);
+ srcList->GetListNickName(str);
+ SetListNickName(str);
+ srcList->GetDescription(str);
+ SetDescription(str);
+
+ nsAutoCString uid;
+ srcList->GetUID(uid);
+ SetUID(uid);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::Init(const char* aURI) {
+ mURI = aURI;
+ mIsValidURI = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::CleanUp(JSContext* cx, Promise** retval) {
+ nsIGlobalObject* globalObject =
+ xpc::NativeGlobal(JS::CurrentGlobalOrNull(cx));
+ if (NS_WARN_IF(!globalObject)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ ErrorResult result;
+ RefPtr<Promise> promise = Promise::Create(globalObject, result);
+ promise->MaybeResolveWithUndefined();
+ promise.forget(retval);
+
+ return NS_OK;
+}
+
+// nsIAbDirectory NOT IMPLEMENTED methods
+NS_IMETHODIMP
+nsAbDirProperty::GetChildNodes(nsTArray<RefPtr<nsIAbDirectory>>& childList) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::GetChildCardCount(uint32_t* count) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::GetChildCards(nsTArray<RefPtr<nsIAbCard>>& childCards) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::DeleteDirectory(nsIAbDirectory* directory) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::HasCard(nsIAbCard* cards, bool* hasCard) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::HasDirectory(nsIAbDirectory* dir, bool* hasDir) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::HasMailListWithName(const nsAString& aName, bool* aHasList) {
+ NS_ENSURE_ARG_POINTER(aHasList);
+
+ *aHasList = false;
+ nsCOMPtr<nsIAbDirectory> aDir;
+ nsresult rv = GetMailListFromName(aName, getter_AddRefs(aDir));
+
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (aDir) {
+ *aHasList = true;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::AddMailList(nsIAbDirectory* list,
+ nsIAbDirectory** addedList) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::EditMailListToDatabase(nsIAbCard* listCard) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::AddCard(nsIAbCard* childCard,
+ nsIAbCard** addedCard) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::ModifyCard(nsIAbCard* aModifiedCard) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::DeleteCards(
+ const nsTArray<RefPtr<nsIAbCard>>& aCards) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::DropCard(nsIAbCard* childCard,
+ bool needToCopyCard) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::CardForEmailAddress(
+ const nsACString& aEmailAddress, nsIAbCard** aAbCard) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetCardFromProperty(const char* aProperty,
+ const nsACString& aValue,
+ bool caseSensitive,
+ nsIAbCard** result) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetCardsFromProperty(
+ const char* aProperty, const nsACString& aValue, bool caseSensitive,
+ nsTArray<RefPtr<nsIAbCard>>& result) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAbDirProperty::GetMailListFromName(const nsAString& aName,
+ nsIAbDirectory** aResult) {
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ *aResult = nullptr;
+ bool supportsLists = false;
+ nsresult rv = GetSupportsMailingLists(&supportsLists);
+ if (NS_FAILED(rv) || !supportsLists) return NS_OK;
+
+ if (m_IsMailList) return NS_OK;
+
+ if (!m_AddressList) {
+ nsresult rv;
+ m_AddressList = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ uint32_t listCount = 0;
+ rv = m_AddressList->GetLength(&listCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (uint32_t i = 0; i < listCount; i++) {
+ nsCOMPtr<nsIAbDirectory> listDir(do_QueryElementAt(m_AddressList, i, &rv));
+ if (NS_SUCCEEDED(rv) && listDir) {
+ nsAutoString listName;
+ rv = listDir->GetDirName(listName);
+ if (NS_SUCCEEDED(rv) && listName.Equals(aName)) {
+ listDir.forget(aResult);
+ return NS_OK;
+ }
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetSupportsMailingLists(
+ bool* aSupportsMailingsLists) {
+ NS_ENSURE_ARG_POINTER(aSupportsMailingsLists);
+ // We don't currently support nested mailing lists, so only return true if
+ // we're not a mailing list.
+ *aSupportsMailingsLists = !m_IsMailList;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetReadOnly(bool* aReadOnly) {
+ NS_ENSURE_ARG_POINTER(aReadOnly);
+ // Default is that we are writable. Any implementation that is read-only must
+ // override this method.
+ *aReadOnly = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetIsRemote(bool* aIsRemote) {
+ NS_ENSURE_ARG_POINTER(aIsRemote);
+ *aIsRemote = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetIsSecure(bool* aIsSecure) {
+ NS_ENSURE_ARG_POINTER(aIsSecure);
+ *aIsSecure = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::UseForAutocomplete(
+ const nsACString& aIdentityKey, bool* aResult) {
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ // Is local autocomplete enabled?
+ nsresult rv;
+ nsCOMPtr<nsIPrefBranch> prefBranch(
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = prefBranch->GetBoolPref("mail.enable_autocomplete", aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // If autocomplete is generally enabled, check if it has been disabled
+ // explicitly for this directory.
+ if (*aResult) {
+ (void)GetBoolValue("enable_autocomplete", true, aResult);
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetDirPrefId(nsACString& aDirPrefId) {
+ aDirPrefId = m_DirPrefId;
+ return NS_OK;
+}
+
+nsresult nsAbDirProperty::InitDirectoryPrefs() {
+ if (m_DirPrefId.IsEmpty()) return NS_ERROR_NOT_INITIALIZED;
+
+ nsresult rv;
+ nsCOMPtr<nsIPrefService> prefService(
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString realPrefId(m_DirPrefId);
+ realPrefId.Append('.');
+
+ return prefService->GetBranch(realPrefId.get(),
+ getter_AddRefs(m_DirectoryPrefs));
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetIntValue(const char* aName,
+ int32_t aDefaultValue,
+ int32_t* aResult) {
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ if (NS_FAILED(m_DirectoryPrefs->GetIntPref(aName, aResult)))
+ *aResult = aDefaultValue;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetBoolValue(const char* aName,
+ bool aDefaultValue, bool* aResult) {
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ if (NS_FAILED(m_DirectoryPrefs->GetBoolPref(aName, aResult)))
+ *aResult = aDefaultValue;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::GetStringValue(const char* aName,
+ const nsACString& aDefaultValue,
+ nsACString& aResult) {
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsCString value;
+
+ /* unfortunately, there may be some prefs out there which look like (null) */
+ if (NS_SUCCEEDED(m_DirectoryPrefs->GetCharPref(aName, value)) &&
+ !value.EqualsLiteral("(null"))
+ aResult = value;
+ else
+ aResult = aDefaultValue;
+
+ return NS_OK;
+}
+/*
+ * Get localized unicode string pref from properties file, convert into an
+ * UTF8 string since address book prefs store as UTF8 strings. So far there
+ * are 2 default prefs stored in addressbook.properties.
+ * "ldap_2.servers.pab.description"
+ * "ldap_2.servers.history.description"
+ */
+NS_IMETHODIMP nsAbDirProperty::GetLocalizedStringValue(
+ const char* aName, const nsACString& aDefaultValue, nsACString& aResult) {
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsString wvalue;
+ nsCOMPtr<nsIPrefLocalizedString> locStr;
+
+ nsresult rv = m_DirectoryPrefs->GetComplexValue(
+ aName, NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(locStr));
+ if (NS_SUCCEEDED(rv)) {
+ rv = locStr->ToString(getter_Copies(wvalue));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ if (wvalue.IsEmpty())
+ aResult = aDefaultValue;
+ else
+ CopyUTF16toUTF8(wvalue, aResult);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetIntValue(const char* aName, int32_t aValue) {
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ return m_DirectoryPrefs->SetIntPref(aName, aValue);
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetBoolValue(const char* aName, bool aValue) {
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ return m_DirectoryPrefs->SetBoolPref(aName, aValue);
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetStringValue(const char* aName,
+ const nsACString& aValue) {
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ return m_DirectoryPrefs->SetCharPref(aName, aValue);
+}
+
+NS_IMETHODIMP nsAbDirProperty::SetLocalizedStringValue(
+ const char* aName, const nsACString& aValue) {
+ if (!m_DirectoryPrefs && NS_FAILED(InitDirectoryPrefs()))
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsresult rv;
+ nsCOMPtr<nsIPrefLocalizedString> locStr(
+ do_CreateInstance(NS_PREFLOCALIZEDSTRING_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = locStr->SetData(NS_ConvertUTF8toUTF16(aValue));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return m_DirectoryPrefs->SetComplexValue(
+ aName, NS_GET_IID(nsIPrefLocalizedString), locStr);
+}
+
+NS_IMETHODIMP nsAbDirProperty::Search(const nsAString& query,
+ const nsAString& searchString,
+ nsIAbDirSearchListener* listener) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}