From c61730c176c3249ed187cbf6833630d3ac777bcf Mon Sep 17 00:00:00 2001 From: "sspitzer%netscape.com" Date: Sat, 9 Mar 2002 05:51:10 +0000 Subject: [PATCH] fix for #126134. when offline, LDAP autocomplete searches and addressbook searches should use the "replicated" .mab file these changes are needed for the LDAP replication feature. fix for #116984. don't hard code maxHits to 100, use the per-ldap-addressbook pref value instead. r=dmose,sr=bienvenu,a=dbaron --- .../addrbook/src/nsAbAutoCompleteSession.cpp | 112 ++++++++++++++++-- .../addrbook/src/nsAbAutoCompleteSession.h | 17 ++- mailnews/addrbook/src/nsAbLDAPDirectory.cpp | 110 ++++++++++++----- 3 files changed, 193 insertions(+), 46 deletions(-) diff --git a/mailnews/addrbook/src/nsAbAutoCompleteSession.cpp b/mailnews/addrbook/src/nsAbAutoCompleteSession.cpp index 750489fbc45..2f8feefacf1 100644 --- a/mailnews/addrbook/src/nsAbAutoCompleteSession.cpp +++ b/mailnews/addrbook/src/nsAbAutoCompleteSession.cpp @@ -49,8 +49,10 @@ #include "nsMsgBaseCID.h" #include "nsMsgI18N.h" #include "nsIMsgIdentity.h" -#include "nsIPref.h" #include "prmem.h" +#include "nsNetCID.h" +#include "nsIIOService.h" +#include "nsIPref.h" NS_IMPL_ISUPPORTS2(nsAbAutoCompleteSession, nsIAbAutoCompleteSession, nsIAutoCompleteSession) @@ -491,8 +493,73 @@ nsresult nsAbAutoCompleteSession::SearchCards(nsIAbDirectory* directory, nsAbAut return NS_OK; } +nsresult +nsAbAutoCompleteSession::NeedToSearchLocalDirectories(nsIPref *aPrefs, PRBool *aNeedToSearch) +{ + NS_ENSURE_ARG_POINTER(aPrefs); + NS_ENSURE_ARG_POINTER(aNeedToSearch); -nsresult nsAbAutoCompleteSession::SearchDirectory(const char *aURI, nsAbAutoCompleteSearchString* searchStr, nsIAutoCompleteResults* results, PRBool searchSubDirectory) + nsresult rv = aPrefs->GetBoolPref("mail.enable_autocomplete", aNeedToSearch); + NS_ENSURE_SUCCESS(rv,rv); + return NS_OK; +} + +nsresult +nsAbAutoCompleteSession::NeedToSearchReplicatedLDAPDirectories(nsIPref *aPrefs, PRBool *aNeedToSearch) +{ + NS_ENSURE_ARG_POINTER(aPrefs); + NS_ENSURE_ARG_POINTER(aNeedToSearch); + + // first check if the user is set up to do LDAP autocompletion + nsresult rv = aPrefs->GetBoolPref("ldap_2.autoComplete.useDirectory", aNeedToSearch); + NS_ENSURE_SUCCESS(rv, rv); + + // no need to search if not set up for LDAP autocompletion + if (!*aNeedToSearch) + return NS_OK; + + // now see if we are offline, if we are we need to search the + // replicated directory + nsCOMPtr ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); + rv = ioService->GetOffline(aNeedToSearch); + NS_ENSURE_SUCCESS(rv,rv); + return NS_OK; +} + +nsresult +nsAbAutoCompleteSession::SearchReplicatedLDAPDirectories(nsIPref *aPref, nsAbAutoCompleteSearchString* searchStr, PRBool searchSubDirectory, nsIAutoCompleteResults* results) +{ + NS_ENSURE_ARG_POINTER(aPref); + + nsXPIDLCString prefName; + nsresult rv = aPref->CopyCharPref("ldap_2.autoComplete.directoryServer", getter_Copies(prefName)); + NS_ENSURE_SUCCESS(rv,rv); + + if (prefName.IsEmpty()) + return NS_OK; + + // use the prefName to get the fileName pref + nsCAutoString fileNamePref; + fileNamePref = prefName + NS_LITERAL_CSTRING(".filename"); + + nsXPIDLCString fileName; + rv = aPref->CopyCharPref(fileNamePref.get(), getter_Copies(fileName)); + NS_ENSURE_SUCCESS(rv,rv); + + // if there is no fileName, bail out now. + if (fileName.IsEmpty()) + return NS_OK; + + // use the fileName to create the URI for the replicated directory + nsCAutoString URI; + URI = NS_LITERAL_CSTRING("moz-abmdbdirectory://") + fileName; + + // and then search the replicated directory + return SearchDirectory(URI.get(), searchStr, searchSubDirectory, results); +} + +nsresult nsAbAutoCompleteSession::SearchDirectory(const char *aURI, nsAbAutoCompleteSearchString* searchStr, PRBool searchSubDirectory, nsIAutoCompleteResults* results) { nsresult rv = NS_OK; nsCOMPtr rdfService(do_GetService("@mozilla.org/rdf/rdf-service;1", &rv)); @@ -541,7 +608,7 @@ nsresult nsAbAutoCompleteSession::SearchDirectory(const char *aURI, nsAbAutoComp { nsXPIDLCString URI; subResource->GetValue(getter_Copies(URI)); - rv = SearchDirectory(URI.get(), searchStr, results, PR_TRUE); + rv = SearchDirectory(URI.get(), searchStr, PR_TRUE, results); } } } @@ -620,14 +687,19 @@ NS_IMETHODIMP nsAbAutoCompleteSession::OnStartLookup(const PRUnichar *uSearchStr if (!listener) return NS_ERROR_NULL_POINTER; - PRBool enableAutocomplete = PR_TRUE; + PRBool enableLocalAutocomplete; + PRBool enableReplicatedLDAPAutocomplete; - nsCOMPtr pPref(do_GetService(NS_PREF_CONTRACTID, &rv)); + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); - pPref->GetBoolPref("mail.enable_autocomplete", &enableAutocomplete); + rv = NeedToSearchLocalDirectories(prefs, &enableLocalAutocomplete); + NS_ENSURE_SUCCESS(rv,rv); - if (uSearchString[0] == 0 || enableAutocomplete == PR_FALSE) + rv = NeedToSearchReplicatedLDAPDirectories(prefs, &enableReplicatedLDAPAutocomplete); + NS_ENSURE_SUCCESS(rv,rv); + + if (uSearchString[0] == 0 || (!enableLocalAutocomplete && !enableReplicatedLDAPAutocomplete)) { listener->OnAutoComplete(nsnull, nsIAutoCompleteStatus::ignored); return NS_OK; @@ -636,7 +708,7 @@ NS_IMETHODIMP nsAbAutoCompleteSession::OnStartLookup(const PRUnichar *uSearchStr // figure out what we're supposed to do about the comment column, and // remember it for when the results start coming back // - rv = pPref->GetIntPref("mail.autoComplete.commentColumn", + rv = prefs->GetIntPref("mail.autoComplete.commentColumn", &mAutoCompleteCommentColumn); if (NS_FAILED(rv)) { mAutoCompleteCommentColumn = 0; @@ -657,8 +729,28 @@ NS_IMETHODIMP nsAbAutoCompleteSession::OnStartLookup(const PRUnichar *uSearchStr if (NS_SUCCEEDED(rv)) if (NS_FAILED(SearchPreviousResults(&searchStrings, previousSearchResult, results))) { - rv = SearchDirectory(kAllDirectoryRoot, &searchStrings, results, PR_TRUE); - } + nsresult rv1,rv2; + + if (enableLocalAutocomplete) { + rv1 = SearchDirectory(kAllDirectoryRoot, &searchStrings, PR_TRUE, results); + NS_ASSERTION(NS_SUCCEEDED(rv1), "searching all local directories failed"); + } + else + rv1 = NS_OK; + + if (enableReplicatedLDAPAutocomplete) { + rv2 = SearchReplicatedLDAPDirectories(prefs, &searchStrings, PR_TRUE, results); + NS_ASSERTION(NS_SUCCEEDED(rv2), "searching all replicated LDAP directories failed"); + } + else + rv2 = NS_OK; + + // only bail out if both failed. otherwise, we have some results we can use + if (NS_FAILED(rv1) && NS_FAILED(rv2)) + rv = NS_ERROR_FAILURE; + else + rv = NS_OK; + } AutoCompleteStatus status = nsIAutoCompleteStatus::failed; if (NS_SUCCEEDED(rv) && results) diff --git a/mailnews/addrbook/src/nsAbAutoCompleteSession.h b/mailnews/addrbook/src/nsAbAutoCompleteSession.h index 77d27595be4..0da77adb524 100644 --- a/mailnews/addrbook/src/nsAbAutoCompleteSession.h +++ b/mailnews/addrbook/src/nsAbAutoCompleteSession.h @@ -44,6 +44,7 @@ #include "nsIAbDirectory.h" #include "nsIAbAutoCompleteSession.h" +class nsIPref; typedef struct { @@ -104,12 +105,9 @@ protected: const PRUnichar* pEmailStr, const PRUnichar* pNotes, const PRUnichar* pDirName, PRBool bIsMailList, MatchType type, nsIAutoCompleteResults* results); - PRBool CheckEntry(nsAbAutoCompleteSearchString* searchStr, const PRUnichar* nickName,const PRUnichar* displayName, + PRBool CheckEntry(nsAbAutoCompleteSearchString* searchStr, const PRUnichar* nickName,const PRUnichar* displayName, const PRUnichar* firstName, const PRUnichar* lastName, const PRUnichar* emailAddress, MatchType* matchType); - nsresult SearchCards(nsIAbDirectory* directory, nsAbAutoCompleteSearchString* searchStr, nsIAutoCompleteResults* results); - nsresult SearchDirectory(const char *aURI, nsAbAutoCompleteSearchString* searchStr, nsIAutoCompleteResults* results, PRBool searchSubDirectory = PR_FALSE); - nsresult SearchPreviousResults(nsAbAutoCompleteSearchString *uSearchString, nsIAutoCompleteResults *previousSearchResult, nsIAutoCompleteResults* results); - + nsCOMPtr mParser; nsString mDefaultDomain; PRUint32 mMatchTypeConters[LAST_MATCH_TYPE]; @@ -124,6 +122,15 @@ protected: // 2 = other per-addressbook format (currrently unused here) // PRInt32 mAutoCompleteCommentColumn; + +private: + nsresult SearchCards(nsIAbDirectory* directory, nsAbAutoCompleteSearchString* searchStr, nsIAutoCompleteResults* results); + nsresult SearchDirectory(const char *aURI, nsAbAutoCompleteSearchString* searchStr, PRBool searchSubDirectory, nsIAutoCompleteResults* results); + nsresult SearchPreviousResults(nsAbAutoCompleteSearchString *uSearchString, nsIAutoCompleteResults *previousSearchResult, nsIAutoCompleteResults* results); + + nsresult SearchReplicatedLDAPDirectories(nsIPref *aPrefs, nsAbAutoCompleteSearchString* searchStr, PRBool searchSubDirectory, nsIAutoCompleteResults* results); + nsresult NeedToSearchReplicatedLDAPDirectories(nsIPref *aPrefs, PRBool *aNeedToSearch); + nsresult NeedToSearchLocalDirectories(nsIPref *aPrefs, PRBool *aNeedToSearch); }; diff --git a/mailnews/addrbook/src/nsAbLDAPDirectory.cpp b/mailnews/addrbook/src/nsAbLDAPDirectory.cpp index 787b966f727..f8b6afd88e2 100644 --- a/mailnews/addrbook/src/nsAbLDAPDirectory.cpp +++ b/mailnews/addrbook/src/nsAbLDAPDirectory.cpp @@ -46,12 +46,12 @@ #include "nsIAddrBookSession.h" #include "nsIRDFService.h" -#include "nsIPref.h" - #include "nsString.h" #include "nsXPIDLString.h" #include "nsAutoLock.h" - +#include "nsNetCID.h" +#include "nsIIOService.h" +#include "nsIPref.h" nsAbLDAPDirectory::nsAbLDAPDirectory() : nsAbDirectoryRDFResource(), @@ -107,20 +107,19 @@ nsresult nsAbLDAPDirectory::InitiateConnection () mURL = do_CreateInstance(NS_LDAPURL_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr pref(do_GetService(NS_PREF_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv,rv); - - // turn mURINoQuery into a pref name; - // moz-abldapdirectory://ldap_2.servers.nscpphonebook into -> "ldap_2.servers.nscpphonebook.uri" + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + // use mURINoQuery to get a prefName nsCAutoString prefName; prefName = nsDependentCString(mURINoQuery.get() + kLDAPDirectoryRootLen) + NS_LITERAL_CSTRING(".uri"); - nsXPIDLCString ldapURL; - rv = pref->CopyCharPref(prefName.get(), getter_Copies(ldapURL)); + // turn moz-abldapdirectory://ldap_2.servers.nscpphonebook into -> "ldap_2.servers.nscpphonebook.uri" + nsXPIDLCString URI; + rv = prefs->CopyCharPref(prefName.get(), getter_Copies(URI)); NS_ENSURE_SUCCESS(rv,rv); - - rv = mURL->SetSpec(ldapURL); + + rv = mURL->SetSpec(URI); NS_ENSURE_SUCCESS(rv, rv); mConnection = do_CreateInstance(NS_LDAPCONNECTION_CONTRACTID, &rv); @@ -157,16 +156,60 @@ NS_IMETHODIMP nsAbLDAPDirectory::GetChildCards(nsIEnumerator** result) { nsresult rv; - // Start the search - rv = StartSearch (); - NS_ENSURE_SUCCESS(rv, rv); + // when offline, we need to get the child cards for the local, replicated mdb directory + PRBool offline; + nsCOMPtr ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); + rv = ioService->GetOffline(&offline); + NS_ENSURE_SUCCESS(rv,rv); + + if (mIsQueryURI && offline) { + nsCOMPtr rdfService = do_GetService("@mozilla.org/rdf/rdf-service;1",&rv); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr array; - NS_NewISupportsArray(getter_AddRefs(array)); - if (!array) - return NS_ERROR_OUT_OF_MEMORY; + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); - return array->Enumerate(result); + // use mURINoQuery to get a prefName + nsCAutoString prefName; + prefName = nsDependentCString(mURINoQuery.get() + kLDAPDirectoryRootLen) + NS_LITERAL_CSTRING(".filename"); + + nsXPIDLCString fileName; + rv = prefs->CopyCharPref(prefName.get(), getter_Copies(fileName)); + NS_ENSURE_SUCCESS(rv,rv); + + // if there is no fileName, bail out now. + if (fileName.IsEmpty()) + return NS_OK; + + // perform the same query, but on the local directory + nsCAutoString localDirectoryURI; + localDirectoryURI = NS_LITERAL_CSTRING("moz-abmdbdirectory://") + fileName + NS_LITERAL_CSTRING("?") + mQueryString; + + nsCOMPtr resource; + rv = rdfService->GetResource(localDirectoryURI.get(), getter_AddRefs(resource)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr directory = do_QueryInterface(resource, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = directory->GetChildCards(result); + } + else { + // Start the search + rv = StartSearch(); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr array; + NS_NewISupportsArray(getter_AddRefs(array)); + if (!array) + return NS_ERROR_OUT_OF_MEMORY; + + rv = array->Enumerate(result); + } + + NS_ENSURE_SUCCESS(rv,rv); + return rv; } NS_IMETHODIMP nsAbLDAPDirectory::HasCard(nsIAbCard* card, PRBool* hasCard) @@ -272,24 +315,29 @@ NS_IMETHODIMP nsAbLDAPDirectory::StartSearch () new nsAbDirSearchListener (this); queryListener = _queryListener; - // Perform the query - // - // XXX todo, instead of 100, use the ldap_2.servers.xxx.maxHits pref - // the problem is how to get that value here. - // - // I'm thinking that nsAbDirectories should know their key so that - // they can do a lookup of server values from the key, when they need it - // (as those values can change) - rv = DoQuery(arguments, queryListener, 100, 0, &mContext); + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); - + + // use mURINoQuery to get a prefName + nsCAutoString prefName; + prefName = nsDependentCString(mURINoQuery.get() + kLDAPDirectoryRootLen) + NS_LITERAL_CSTRING(".maxHits"); + + // turn moz-abldapdirectory://ldap_2.servers.nscpphonebook into -> "ldap_2.servers.nscpphonebook.maxHits" + PRInt32 maxHits; + rv = prefs->GetIntPref(prefName.get(), &maxHits); + NS_ENSURE_SUCCESS(rv,rv); + + // Perform the query + rv = DoQuery(arguments, queryListener, maxHits, 0, &mContext); + NS_ENSURE_SUCCESS(rv, rv); + // Enter lock nsAutoLock lock (mLock); mPerformingQuery = PR_TRUE; mCache.Reset (); return rv; -} +} NS_IMETHODIMP nsAbLDAPDirectory::StopSearch () {