summaryrefslogtreecommitdiffstats
path: root/mailnews/addrbook/src/nsAbBSDirectory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mailnews/addrbook/src/nsAbBSDirectory.cpp')
-rw-r--r--mailnews/addrbook/src/nsAbBSDirectory.cpp323
1 files changed, 323 insertions, 0 deletions
diff --git a/mailnews/addrbook/src/nsAbBSDirectory.cpp b/mailnews/addrbook/src/nsAbBSDirectory.cpp
new file mode 100644
index 000000000..0d018bbda
--- /dev/null
+++ b/mailnews/addrbook/src/nsAbBSDirectory.cpp
@@ -0,0 +1,323 @@
+/* -*- 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 "nsIPrefService.h"
+#include "nsAbBSDirectory.h"
+
+#include "nsDirPrefs.h"
+#include "nsAbBaseCID.h"
+#include "nsAddrDatabase.h"
+#include "nsIAbManager.h"
+#include "nsIAbMDBDirectory.h"
+#include "nsServiceManagerUtils.h"
+#include "nsAbDirFactoryService.h"
+#include "nsAbMDBDirFactory.h"
+#include "nsArrayEnumerator.h"
+
+#include "nsCRTGlue.h"
+
+nsAbBSDirectory::nsAbBSDirectory()
+: mInitialized(false)
+, mServers(13)
+{
+}
+
+nsAbBSDirectory::~nsAbBSDirectory()
+{
+}
+
+NS_IMETHODIMP nsAbBSDirectory::Init(const char *aURI)
+{
+ mURI = aURI;
+ return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsAbBSDirectory, nsAbDirProperty)
+
+nsresult nsAbBSDirectory::CreateDirectoriesFromFactory(const nsACString &aURI,
+ DIR_Server *aServer,
+ bool aNotify)
+{
+ nsresult rv;
+
+ // Get the directory factory service
+ nsCOMPtr<nsIAbDirFactoryService> dirFactoryService =
+ do_GetService(NS_ABDIRFACTORYSERVICE_CONTRACTID,&rv);
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ // Get the directory factory from the URI
+ nsCOMPtr<nsIAbDirFactory> dirFactory;
+ rv = dirFactoryService->GetDirFactory(aURI, getter_AddRefs(dirFactory));
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ // Create the directories
+ nsCOMPtr<nsISimpleEnumerator> newDirEnumerator;
+ rv = dirFactory->GetDirectories(NS_ConvertUTF8toUTF16(aServer->description),
+ aURI,
+ nsDependentCString(aServer->prefName),
+ getter_AddRefs(newDirEnumerator));
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ // Enumerate through the directories adding them
+ // to the sub directories array
+ bool hasMore;
+ nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
+
+ while (NS_SUCCEEDED(newDirEnumerator->HasMoreElements(&hasMore)) && hasMore)
+ {
+ nsCOMPtr<nsISupports> newDirSupports;
+ rv = newDirEnumerator->GetNext(getter_AddRefs(newDirSupports));
+ if(NS_FAILED(rv))
+ continue;
+
+ nsCOMPtr<nsIAbDirectory> childDir = do_QueryInterface(newDirSupports, &rv);
+ if(NS_FAILED(rv))
+ continue;
+
+ // Define a relationship between the preference
+ // entry and the directory
+ mServers.Put(childDir, aServer);
+
+ mSubDirectories.AppendObject(childDir);
+
+ if (aNotify && abManager)
+ abManager->NotifyDirectoryItemAdded(this, childDir);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbBSDirectory::GetChildNodes(nsISimpleEnumerator* *aResult)
+{
+ nsresult rv = EnsureInitialized();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_NewArrayEnumerator(aResult, mSubDirectories);
+}
+
+nsresult nsAbBSDirectory::EnsureInitialized()
+{
+ if (mInitialized)
+ return NS_OK;
+
+ nsresult rv;
+ nsCOMPtr<nsIAbDirFactoryService> dirFactoryService =
+ do_GetService(NS_ABDIRFACTORYSERVICE_CONTRACTID,&rv);
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ nsTArray<DIR_Server*> *directories = DIR_GetDirectories();
+ if (!directories)
+ return NS_ERROR_FAILURE;
+
+ int32_t count = directories->Length();
+ for (int32_t i = 0; i < count; i++)
+ {
+ DIR_Server *server = directories->ElementAt(i);
+
+ // if this is a 4.x, local .na2 addressbook (PABDirectory)
+ // we must skip it.
+ // mozilla can't handle 4.x .na2 addressbooks
+ // note, the filename might be na2 for 4.x LDAP directories
+ // (we used the .na2 file for replication), and we don't want to skip
+ // those. see bug #127007
+ uint32_t fileNameLen = strlen(server->fileName);
+ if (((fileNameLen > kABFileName_PreviousSuffixLen) &&
+ strcmp(server->fileName + fileNameLen - kABFileName_PreviousSuffixLen,
+ kABFileName_PreviousSuffix) == 0) &&
+ (server->dirType == PABDirectory))
+ continue;
+
+ // Set the uri property
+ nsAutoCString URI (server->uri);
+ // This is in case the uri is never set
+ // in the nsDirPref.cpp code.
+ if (!server->uri)
+ {
+ URI = NS_LITERAL_CSTRING(kMDBDirectoryRoot);
+ URI += nsDependentCString(server->fileName);
+ }
+
+ /*
+ * Check that we are not converting from a
+ * a 4.x address book file e.g. pab.na2
+ * check if the URI ends with ".na2"
+ */
+ if (StringEndsWith(URI, NS_LITERAL_CSTRING(kABFileName_PreviousSuffix)))
+ URI.Replace(kMDBDirectoryRootLen, URI.Length() - kMDBDirectoryRootLen, server->fileName);
+
+ // Create the directories
+ rv = CreateDirectoriesFromFactory(URI, server, false /* notify */);
+
+ // If we failed, this could be because something has set a pref for us
+ // which is now broke (e.g. no factory present). So just ignore this one
+ // and move on.
+ if (NS_FAILED(rv))
+ NS_WARNING("CreateDirectoriesFromFactory failed - Invalid factory?");
+ }
+
+ mInitialized = true;
+ // sort directories by position...
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbBSDirectory::CreateNewDirectory(const nsAString &aDirName,
+ const nsACString &aURI,
+ uint32_t aType,
+ const nsACString &aPrefName,
+ nsACString &aResult)
+{
+ nsresult rv = EnsureInitialized();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ /*
+ * TODO
+ * This procedure is still MDB specific
+ * due to the dependence on the current
+ * nsDirPref.cpp code
+ */
+
+ nsCString URI(aURI);
+
+ /*
+ * The creation of the address book in the preferences
+ * is very MDB implementation specific.
+ * If the fileName attribute is null then it will
+ * create an appropriate file name.
+ * Somehow have to resolve this issue so that it
+ * is more general.
+ *
+ */
+ DIR_Server* server = nullptr;
+ rv = DIR_AddNewAddressBook(aDirName, EmptyCString(), URI,
+ (DirectoryType)aType, aPrefName, &server);
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ if (aType == PABDirectory) {
+ // Add the URI property
+ URI.AssignLiteral(kMDBDirectoryRoot);
+ URI.Append(nsDependentCString(server->fileName));
+ }
+
+ aResult.Assign(server->prefName);
+
+ rv = CreateDirectoriesFromFactory(URI, server, true /* notify */);
+ NS_ENSURE_SUCCESS(rv,rv);
+ return rv;
+}
+
+NS_IMETHODIMP nsAbBSDirectory::CreateDirectoryByURI(const nsAString &aDisplayName,
+ const nsACString &aURI)
+{
+ nsresult rv = EnsureInitialized();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString fileName;
+ if (StringBeginsWith(aURI, NS_LITERAL_CSTRING(kMDBDirectoryRoot)))
+ fileName = Substring(aURI, kMDBDirectoryRootLen);
+
+ DIR_Server * server = nullptr;
+ rv = DIR_AddNewAddressBook(aDisplayName, fileName, aURI,
+ PABDirectory, EmptyCString(), &server);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = CreateDirectoriesFromFactory(aURI, server, true /* notify */);
+ NS_ENSURE_SUCCESS(rv,rv);
+ return rv;
+}
+
+NS_IMETHODIMP nsAbBSDirectory::DeleteDirectory(nsIAbDirectory *directory)
+{
+ NS_ENSURE_ARG_POINTER(directory);
+
+ nsresult rv = EnsureInitialized();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ DIR_Server *server = nullptr;
+ mServers.Get(directory, &server);
+
+ if (!server)
+ return NS_ERROR_FAILURE;
+
+ struct GetDirectories
+ {
+ GetDirectories(DIR_Server* aServer) : mServer(aServer) { }
+
+ nsCOMArray<nsIAbDirectory> directories;
+ DIR_Server* mServer;
+ };
+ GetDirectories getDirectories(server);
+ for (auto iter = mServers.Iter(); !iter.Done(); iter.Next()) {
+ if (iter.UserData() == getDirectories.mServer) {
+ nsCOMPtr<nsIAbDirectory> abDir = do_QueryInterface(iter.Key());
+ getDirectories.directories.AppendObject(abDir);
+ }
+ }
+
+ DIR_DeleteServerFromList(server);
+
+ nsCOMPtr<nsIAbDirFactoryService> dirFactoryService =
+ do_GetService(NS_ABDIRFACTORYSERVICE_CONTRACTID,&rv);
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ uint32_t count = getDirectories.directories.Count();
+
+ nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID);
+
+ for (uint32_t i = 0; i < count; i++) {
+ nsCOMPtr<nsIAbDirectory> d = getDirectories.directories[i];
+
+ mServers.Remove(d);
+ mSubDirectories.RemoveObject(d);
+
+ if (abManager)
+ abManager->NotifyDirectoryDeleted(this, d);
+
+ nsCString uri;
+ rv = d->GetURI(uri);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIAbDirFactory> dirFactory;
+ rv = dirFactoryService->GetDirFactory(uri, getter_AddRefs(dirFactory));
+ if (NS_FAILED(rv))
+ continue;
+
+ rv = dirFactory->DeleteDirectory(d);
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP nsAbBSDirectory::HasDirectory(nsIAbDirectory *dir, bool *hasDir)
+{
+ if (!hasDir)
+ return NS_ERROR_NULL_POINTER;
+
+ nsresult rv = EnsureInitialized();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ DIR_Server *dirServer = nullptr;
+ mServers.Get(dir, &dirServer);
+ return DIR_ContainsServer(dirServer, hasDir);
+}
+
+NS_IMETHODIMP nsAbBSDirectory::UseForAutocomplete(const nsACString &aIdentityKey,
+ bool *aResult)
+{
+ // For the "root" directory (kAllDirectoryRoot) always return true so that
+ // we can search sub directories that may or may not be local.
+ NS_ENSURE_ARG_POINTER(aResult);
+ *aResult = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsAbBSDirectory::GetURI(nsACString &aURI)
+{
+ if (mURI.IsEmpty())
+ return NS_ERROR_NOT_INITIALIZED;
+
+ aURI = mURI;
+ return NS_OK;
+}
+