Bug 449618 -- Move cardForEmail to nsIAbDirectory r=standard8, sr=dmose
authorJoshua Cranmer <Pidgeot18@gmail.com>
Fri, 15 Aug 2008 22:28:04 -0400
changeset 108 fad5a882c378061de4f6aa3f9582ae8bd8a7eb95
parent 107 2d56d558d2b986266395f69772caed71af981af8
child 109 ae6ed84243e42ccd092bd85d11efa1090e8c7b00
push idunknown
push userunknown
push dateunknown
reviewersstandard8, dmose
bugs449618
Bug 449618 -- Move cardForEmail to nsIAbDirectory r=standard8, sr=dmose This also took the opportunity to do two replacements of RDF with nsIAbManager in code I was already changing.
mail/base/content/mailWindowOverlay.js
mail/base/content/msgHdrViewOverlay.js
mailnews/addrbook/public/nsIAbDirectory.idl
mailnews/addrbook/public/nsIAbMDBDirectory.idl
mailnews/addrbook/src/nsAbDirProperty.cpp
mailnews/addrbook/src/nsAbMDBDirProperty.cpp
mailnews/addrbook/test/unit/test_cardForEmail.js
mailnews/addrbook/test/unit/test_collection.js
mailnews/base/resources/content/junkCommands.js
mailnews/base/resources/content/mailWindowOverlay.js
mailnews/base/search/public/nsMsgSearchTerm.h
mailnews/base/search/src/nsMsgSearchTerm.cpp
mailnews/base/src/nsMsgContentPolicy.cpp
mailnews/base/src/nsMsgContentPolicy.h
mailnews/base/util/nsMsgDBFolder.cpp
--- a/mail/base/content/mailWindowOverlay.js
+++ b/mail/base/content/mailWindowOverlay.js
@@ -2552,23 +2552,25 @@ function allowRemoteContentForSender()
   // search through all of our local address books looking for a match.
   var enumerator = Components.classes["@mozilla.org/abmanager;1"]
                              .getService(Components.interfaces.nsIAbManager)
                              .directories;
   var cardForEmailAddress;
   var addrbook;
   while (!cardForEmailAddress && enumerator.hasMoreElements())
   {
-    addrbook = enumerator.getNext();
-    if (addrbook instanceof Components.interfaces.nsIAbMDBDirectory)
+    addrbook = enumerator.getNext()
+                         .QueryInterface(Components.interfaces.nsIAbDirectory);
+    try {
       cardForEmailAddress = addrbook.cardForEmailAddress(authorEmailAddress);
+    } catch (e) {}
   }
 
   var allowRemoteContent = false;
-  if (cardForEmailAddress && addrbook instanceof Components.interfaces.nsIAbDirectory)
+  if (cardForEmailAddress)
   {
     // set the property for remote content
     cardForEmailAddress.setProperty("AllowRemoteContent", true);
     addrbook.modifyCard(cardForEmailAddress);
     allowRemoteContent = true;
   }
   else
   {
--- a/mail/base/content/msgHdrViewOverlay.js
+++ b/mail/base/content/msgHdrViewOverlay.js
@@ -972,26 +972,19 @@ function useDisplayNameForAddress(emailA
 {
   // For now, if the email address is in the personal address book, then consider this user a 'known' user
   // and use the display name. I could eventually see our rules enlarged to include other local ABs, replicated
   // LDAP directories, and maybe even domain matches (i.e. any email from someone in my company
   // should use the friendly display name)
 
   if (!gPersonalAddressBookDirectory)
   {
-    var dirs = Components.classes["@mozilla.org/abmanager;1"]
-                         .getService(Components.interfaces.nsIAbManager).directories;
-    while (dirs.hasMoreElements) {
-      var dir = dirs.getNext().QueryInterface(Components.interfaces.nsIAbDirectory);
-      if (dir.URI == kPersonalAddressbookUri) {
-        gPersonalAddressBookDirectory = dir.QueryInterface(Components.interfaces.nsIAbMDBDirectory);
-        break;
-      }
-    }
-
+    var manager = Components.classes["@mozilla.org/abmanager;1"]
+                            .getService(Components.interfaces.nsIAbManager);
+    gPersonalAddressBookDirectory = manager.getDirectory(kPersonalAddressbookUri);
     if (!gPersonalAddressBookDirectory)
       return false;
   }
 
   // look up the email address in the database
   return gPersonalAddressBookDirectory.cardForEmailAddress(emailAddress);
 }
 
--- a/mailnews/addrbook/public/nsIAbDirectory.idl
+++ b/mailnews/addrbook/public/nsIAbDirectory.idl
@@ -54,17 +54,17 @@ interface nsIMutableArray;
 #define kCollectedAddressbook      "history.mab"
 #define kCollectedAddressbookUri   "moz-abmdbdirectory://history.mab"
 
 #define kABFileName_PreviousSuffix ".na2" /* final v2 address book format */
 #define kABFileName_PreviousSuffixLen 4
 #define kABFileName_CurrentSuffix ".mab"  /* v3 address book extension */
 %}
 
-[scriptable, uuid(e30c442f-9d83-4f38-8d41-9884e81237a0)]
+[scriptable, uuid(ab55bec3-5bf9-4928-8322-5cff399b7045)]
 interface nsIAbDirectory : nsISupports {
 
   /**
    * The chrome URI to use for bringing up a dialog to edit this directory.
    * When opening the dialog, use a JS argument of
    * {selectedDirectory: thisdir} where thisdir is this directory that you just
    * got the chrome URI from.
    */
@@ -302,9 +302,24 @@ interface nsIAbDirectory : nsISupports {
    *                      be obtained (e.g. dirPrefId isn't set).
    */
   //@{
   void setIntValue(in string aName, in long aValue);
   void setBoolValue(in string aName, in boolean aValue);
   void setStringValue(in string aName, in ACString aValue);
   void setLocalizedStringValue(in string aName, in AUTF8String aValue);
   //@}
+
+  /** 
+   * Returns the address card for the specified email address if found.
+   *
+   * If the address book type does not know how to find a card, it will throw
+   * NS_ERROR_NOT_IMPLEMENTED. Core address book types do throw this exception,
+   * so beware when calling this method.
+   *
+   * @param  emailAddress The email address to find in either the primary or
+   *                      secondary email address fields. If email address is
+   *                      empty, the database won't be searched and the function
+   *                      will return as if no card was found.
+   * @return              An nsIAbCard if one was found, else returns NULL.
+   */
+  nsIAbCard cardForEmailAddress(in AUTF8String emailAddress);
 };
--- a/mailnews/addrbook/public/nsIAbMDBDirectory.idl
+++ b/mailnews/addrbook/public/nsIAbMDBDirectory.idl
@@ -43,17 +43,17 @@ interface nsIAbDirectory;
 interface nsIAbCard;
 interface nsIAddrDatabase;
 
 %{C++
 #define kMDBDirectoryRoot          "moz-abmdbdirectory://"
 #define kMDBDirectoryRootLen       21
 %}
 
-[scriptable, uuid(705a6b63-118c-402d-a835-b07347de5a53)]
+[scriptable, uuid(744072be-1ba0-46bc-af24-46e22567a2ea)]
 interface nsIAbMDBDirectory : nsISupports {
 
 	// Creates an RDF directory component from the
 	// uriName, adds it to its children and returns
 	// the component
 	nsIAbDirectory addDirectory(in string uriName);
 
   /**
@@ -96,20 +96,9 @@ interface nsIAbMDBDirectory : nsISupport
 	void removeEmailAddressAt(in unsigned long aIndex);
 
     attribute unsigned long dbRowID;
 
 	// Empty implementation, called by the data base
 	[noscript] void notifyDirItemAdded(in nsISupports item);
 	
 	[noscript] void clearDatabase();
-	
-  /** 
-   * Returns the address card for the specified email address if found.
-   *
-   * @param  emailAddress The email address to find in either the primary or
-   *                      secondary email address fields. If email address is
-   *                      empty, the database won't be searched and the function
-   *                      will return as if no card was found.
-   * @return              An nsIAbCard if one was found, else returns NULL.
-   */
-  nsIAbCard cardForEmailAddress(in AUTF8String emailAddress);
 };
--- a/mailnews/addrbook/src/nsAbDirProperty.cpp
+++ b/mailnews/addrbook/src/nsAbDirProperty.cpp
@@ -306,16 +306,20 @@ NS_IMETHODIMP nsAbDirProperty::ModifyCar
 { return NS_ERROR_NOT_IMPLEMENTED; }
 
 NS_IMETHODIMP nsAbDirProperty::DeleteCards(nsIArray *cards)
 { return NS_ERROR_NOT_IMPLEMENTED; }
 
 NS_IMETHODIMP nsAbDirProperty::DropCard(nsIAbCard *childCard, PRBool needToCopyCard)
 { return NS_ERROR_NOT_IMPLEMENTED; }
 
+NS_IMETHODIMP nsAbDirProperty::CardForEmailAddress(const nsACString &aEmailAddress,
+                                                   nsIAbCard ** aAbCard)
+{ return NS_ERROR_NOT_IMPLEMENTED; }
+
 NS_IMETHODIMP nsAbDirProperty::GetSupportsMailingLists(PRBool *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;
 }
--- a/mailnews/addrbook/src/nsAbMDBDirProperty.cpp
+++ b/mailnews/addrbook/src/nsAbMDBDirProperty.cpp
@@ -163,21 +163,16 @@ NS_IMETHODIMP nsAbMDBDirProperty::Notify
 }
 
 /* [noscript] void clearDatabase (); */
 NS_IMETHODIMP nsAbMDBDirProperty::ClearDatabase()
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP nsAbMDBDirProperty::CardForEmailAddress(const nsACString &aEmailAddress, nsIAbCard ** aAbCard)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 NS_IMETHODIMP nsAbMDBDirProperty::GetDatabaseFile(nsILocalFile **aResult)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsAbMDBDirProperty::GetDatabase(nsIAddrDatabase **aResult)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
--- a/mailnews/addrbook/test/unit/test_cardForEmail.js
+++ b/mailnews/addrbook/test/unit/test_cardForEmail.js
@@ -1,11 +1,11 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
- * Tests nsIAbMDBDirectory::cardForEmailAddress
+ * Tests nsIAbDirectory::cardForEmailAddress
  * - checks correct return when no email address supplied
  * - checks correct return when no matching email address supplied
  * - checks correct return when matching email address supplied.
  *
  * Uses: cardForEmail.mab
  */
 
 function run_test() {
@@ -14,18 +14,17 @@ function run_test() {
 
   // Copy the file to the profile directory for a PAB
   testAB.copyTo(gProfileDir, kPABData.fileName);
 
   // Test - Get the directory
   var abManager = Components.classes["@mozilla.org/abmanager;1"]
                             .getService(Components.interfaces.nsIAbManager);
 
-  var AB = abManager.getDirectory(kPABData.URI)
-                .QueryInterface(Components.interfaces.nsIAbMDBDirectory);
+  var AB = abManager.getDirectory(kPABData.URI);
 
   // Test - Check that a null string succeeds and does not
   // return a card (bug 404264)
   do_check_true(AB.cardForEmailAddress(null) == null);
 
   // Test - Check that an empty string succeeds and does not
   // return a card (bug 404264)
   do_check_true(AB.cardForEmailAddress("") == null);
--- a/mailnews/addrbook/test/unit/test_collection.js
+++ b/mailnews/addrbook/test/unit/test_collection.js
@@ -259,33 +259,30 @@ function run_test()
 
   // XXX Getting all directories ensures we create all ABs because the
   // address collecter can't currently create ABs itself (bug 314448).
   var temp = abManager.directories;
 
   // Get the actual AB for the collector so we can check cards have been
   // added.
   collectChecker.AB =
-    abManager.getDirectory(prefService.getCharPref("mail.collect_addressbook"))
-             .QueryInterface(Components.interfaces.nsIAbMDBDirectory);
+    abManager.getDirectory(prefService.getCharPref("mail.collect_addressbook"));
 
   // Get the actual collecter
   collectChecker.addressCollect =
     Components.classes["@mozilla.org/addressbook/services/addressCollecter;1"]
               .getService(Components.interfaces.nsIAbAddressCollecter);
 
   // Test - Addition of header without email address.
 
   collectChecker.addressCollect.collectAddress("MyTest <>", true,
                                                nsIAbPMF.unknown);
 
-  var CAB = collectChecker.AB.QueryInterface(Components.interfaces.nsIAbDirectory);
-
   // Address book should have no cards present.
-  do_check_false(CAB.childCards.hasMoreElements());
+  do_check_false(collectChecker.AB.childCards.hasMoreElements());
 
   // Test - Email doesn't exist, but don't add it.
 
   // As we've just set everything up, we know we haven't got anything in the
   // AB, so just try and collect without adding.
   collectChecker.addressCollect.collectAddress(addEmailChecks[0].emailHeader,
                                                false,
                                                addEmailChecks[0].mailFormat);
@@ -298,45 +295,45 @@ function run_test()
 
   collectChecker.part = 0;
 
   addEmailChecks.forEach(collectChecker.checkAddress, collectChecker);
 
   // Test - Do all emails at the same time.
 
   // First delete all existing cards
-  var childCards = CAB.childCards;
+  var childCards = collectChecker.AB.childCards;
   var cardsToDelete = Components.classes["@mozilla.org/array;1"]
                                 .createInstance(Components.interfaces.nsIMutableArray);
   while (childCards.hasMoreElements()) {
     cardsToDelete.appendElement(childCards.getNext(), false);
   }
 
-  CAB.deleteCards(cardsToDelete);
+  collectChecker.AB.deleteCards(cardsToDelete);
 
   // Null these directly, so gc() will purge them
   childCards = null;
   cardsToDelete = null;
 
   // Address book should have no cards present.
-  do_check_false(CAB.childCards.hasMoreElements());
+  do_check_false(collectChecker.AB.childCards.hasMoreElements());
 
   do_check_eq(collectChecker.AB.cardForEmailAddress(addEmailChecks[0].emailHeader), null);
 
   // Now do all emails at the same time.
   collectChecker.checkAll(addEmailChecks);
 
   // Test - Try and modify various emails and formats.
 
   // Add a basic card with just primary and second email to allow testing
   // of the case where we don't modify when second email is matching.
   card = Components.classes["@mozilla.org/addressbook/cardproperty;1"]
                    .createInstance(Components.interfaces.nsIAbCard);
 
   card.primaryEmail = "userprim\u00D0@invalid.com";
   card.setProperty("SecondEmail", "usersec\u00D0@invalid.com");
 
-  CAB.addCard(card);
+  collectChecker.AB.addCard(card);
 
   collectChecker.part = 0;
 
   modifyEmailChecks.forEach(collectChecker.checkAddress, collectChecker);
 };
--- a/mailnews/base/resources/content/junkCommands.js
+++ b/mailnews/base/resources/content/junkCommands.js
@@ -183,32 +183,36 @@ MessageClassifier.prototype =
    *
    * Starts the message classification process for a message. If the message
    * sender's address is in the address book specified by aWhiteListDirectory,
    * the message is skipped.
    *
    * @param aMsgHdr
    *        The header (nsIMsgDBHdr) of the message to classify.
    * @param aWhiteListDirectory
-   *        The addressbook (nsIAbMDBDirectory) to use as a whitelist, or null
+   *        The addressbook (nsIAbDirectory) to use as a whitelist, or null
    *        if no whitelisting should be done.
    */
   analyzeMessage: function(aMsgHdr, aWhiteListDirectory)
   {
     var junkscoreorigin = aMsgHdr.getStringProperty("junkscoreorigin");
     if (junkscoreorigin == "user") // don't override user-set junk status
       return;
 
     // if a whitelist addressbook was specified, check if the email address is in it
     if (aWhiteListDirectory)
     {
       var headerParser = Components.classes["@mozilla.org/messenger/headerparser;1"]
                                    .getService(Components.interfaces.nsIMsgHeaderParser);
       var authorEmailAddress = headerParser.extractHeaderAddressMailboxes(null, aMsgHdr.author);
-      if (aWhiteListDirectory.cardForEmailAddress(authorEmailAddress))
+      var abCard = false;
+      try {
+        abCard = aWhiteListDirectory.cardForEmailAddress(authorEmailAddress);
+      } catch (e) {}
+      if (abCard)
       {
         // message is ham from whitelist
         {
           var db = aMsgHdr.folder.getMsgDatabase(msgWindow);
           db.setStringProperty(aMsgHdr.messageKey, "junkscore", Components.interfaces.nsIJunkMailPlugin.IS_HAM_SCORE);
           db.setStringProperty(aMsgHdr.messageKey, "junkscoreorigin", "whitelist");
           this.mGoodMsgHdrs.appendElement(aMsgHdr, false);
         }
@@ -353,18 +357,20 @@ function processFolderForJunk(aAll)
   if (!tmpMsgURI)
     return;
 
   var tmpMsgHdr = messenger.messageServiceFromURI(tmpMsgURI).messageURIToMsgHdr(tmpMsgURI);
   var spamSettings = tmpMsgHdr.folder.server.spamSettings;
 
   // if enabled in the spam settings, retrieve whitelist addressbook
   var whiteListDirectory = null;
-  if (spamSettings.useWhiteList && spamSettings.whiteListAbURI)
-    whiteListDirectory = RDF.GetResource(spamSettings.whiteListAbURI).QueryInterface(Components.interfaces.nsIAbMDBDirectory);
+  if (spamSettings.useWhiteList && spamSettings.whiteListAbURI) {
+    whiteListDirectory = Components.classes["@mozilla.org/abmanager;1"]
+                                   .getService(Components.interfaces.nsIAbManager)
+                                   .getDirectory(spamSettings.whiteListAbURI);
 
   // create a classifier instance to classify messages in the folder.
   var msgClassifier = new MessageClassifier(tmpMsgHdr.folder, totalMessages);
 
   for ( i = 0; i < totalMessages; i++)
   {
     var index = aAll ? i : indices[i];
     try
--- a/mailnews/base/resources/content/mailWindowOverlay.js
+++ b/mailnews/base/resources/content/mailWindowOverlay.js
@@ -2301,23 +2301,25 @@ function allowRemoteContentForSender()
   // search through all of our local address books looking for a match.
   var enumerator = Components.classes["@mozilla.org/abmanager;1"]
                              .getService(Components.interfaces.nsIAbManager)
                              .directories;
   var cardForEmailAddress;
   var addrbook;
   while (!cardForEmailAddress && enumerator.hasMoreElements())
   {
-    addrbook = enumerator.getNext();
-    if (addrbook instanceof Components.interfaces.nsIAbMDBDirectory)
+    addrbook = enumerator.getNext()
+                         .QueryInterface(Components.interfaces.nsIAbDirectory);
+    try {
       cardForEmailAddress = addrbook.cardForEmailAddress(authorEmailAddress);
+    } catch (e) {}
   }
 
   var allowRemoteContent = false;
-  if (cardForEmailAddress && addrbook instanceof Components.interfaces.nsIAbDirectory)
+  if (cardForEmailAddress)
   {
     // set the property for remote content
     cardForEmailAddress.setProperty("AllowRemoteContent", true);
     addrbook.modifyCard(cardForEmailAddress);
     allowRemoteContent = true;
   }
   else
   {
--- a/mailnews/base/search/public/nsMsgSearchTerm.h
+++ b/mailnews/base/search/public/nsMsgSearchTerm.h
@@ -41,17 +41,17 @@
 //---------------------------------------------------------------------------
 // nsMsgSearchTerm specifies one criterion, e.g. name contains phil
 //---------------------------------------------------------------------------
 #include "nsIMsgSearchSession.h"
 #include "nsIMsgSearchScopeTerm.h"
 #include "nsIMsgSearchTerm.h"
 
 // needed to search for addresses in address books
-#include "nsIAbMDBDirectory.h"
+#include "nsIAbDirectory.h"
 
 #define EMPTY_MESSAGE_LINE(buf) (buf[0] == '\r' || buf[0] == '\n' || buf[0] == '\0')
 
 class nsMsgSearchTerm : public nsIMsgSearchTerm
 {
 public:
   nsMsgSearchTerm();
   nsMsgSearchTerm (nsMsgSearchAttribValue, nsMsgSearchOpValue, nsIMsgSearchValue *, nsMsgSearchBooleanOperator, const char * arbitraryHeader);
@@ -112,15 +112,15 @@ protected:
   nsresult OutputValue(nsCString &outputStr);
   nsresult ParseAttribute(char *inStream, nsMsgSearchAttribValue *attrib);
   nsresult ParseOperator(char *inStream, nsMsgSearchOpValue *value);
   nsresult ParseValue(char *inStream);
   nsresult InitHeaderAddressParser();
     nsresult InitializeAddressBook();
     nsresult MatchInAddressBook(const char * aAddress, PRBool *pResult);
     // fields used by search in address book
-    nsCOMPtr <nsIAbMDBDirectory> mDirectory;
+    nsCOMPtr <nsIAbDirectory> mDirectory;
 
     PRPackedBool mBeginsGrouping;
     PRPackedBool mEndsGrouping;
 };
 
 #endif
--- a/mailnews/base/search/src/nsMsgSearchTerm.cpp
+++ b/mailnews/base/search/src/nsMsgSearchTerm.cpp
@@ -63,17 +63,16 @@
 #include "nsIMsgFilterPlugin.h"
 #include "nsILocalFile.h"
 #include "nsIRDFService.h"
 #include "nsISupportsObsolete.h"
 #include "nsNetCID.h"
 #include "nsIFileStreams.h"
 #include "nsUnicharUtils.h"
 #include "nsIAbCard.h"
-#include "nsIAbDirectory.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsMemory.h"
 #include <ctype.h>
 #include "nsMsgBaseCID.h"
 #include "nsIMsgTagService.h"
 
 //---------------------------------------------------------------------------
@@ -888,21 +887,18 @@ nsresult nsMsgSearchTerm::MatchBody (nsI
 nsresult nsMsgSearchTerm::InitializeAddressBook()
 {
   // the search attribute value has the URI for the address book we need to load.
   // we need both the database and the directory.
   nsresult rv = NS_OK;
 
   if (mDirectory)
   {
-    nsCOMPtr<nsIAbDirectory> dir(do_QueryInterface(mDirectory, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
-
     nsCString uri;
-    rv = dir->GetURI(uri);
+    rv = mDirectory->GetURI(uri);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!uri.Equals(m_value.string))
       // clear out the directory....we are no longer pointing to the right one
       mDirectory = nsnull;
   }
   if (!mDirectory)
   {
@@ -926,19 +922,21 @@ nsresult nsMsgSearchTerm::MatchInAddress
   *pResult = PR_FALSE;
 
   // Some junkmails have empty From: fields.
   if (aAddress == NULL || strlen(aAddress) == 0)
     return rv;
 
   if (mDirectory)
   {
-    nsIAbCard* cardForAddress;
+    nsIAbCard* cardForAddress = nsnull;
     rv = mDirectory->CardForEmailAddress(nsDependentCString(aAddress),
                                          &cardForAddress);
+    if (NS_FAILED(rv) && rv != NS_ERROR_NOT_IMPLEMENTED)
+      return rv;
     if ((m_operator == nsMsgSearchOp::IsInAB && cardForAddress) || (m_operator == nsMsgSearchOp::IsntInAB && !cardForAddress))
       *pResult = PR_TRUE;
     NS_IF_RELEASE(cardForAddress);
   }
 
   return rv;
 }
 
--- a/mailnews/base/src/nsMsgContentPolicy.cpp
+++ b/mailnews/base/src/nsMsgContentPolicy.cpp
@@ -38,21 +38,19 @@
 
 #include "nsMsgContentPolicy.h"
 #include "nsIServiceManager.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
-#include "nsIRDFService.h"
-#include "nsIRDFResource.h"
 #include "nsIMsgHeaderParser.h"
+#include "nsIAbManager.h"
 #include "nsIAbDirectory.h"
-#include "nsIAbMDBDirectory.h"
 #include "nsIAbCard.h"
 #include "nsIMsgMailNewsUrl.h"
 #include "nsIMsgWindow.h"
 #include "nsIMimeMiscStatus.h"
 #include "nsIMsgMessageService.h"
 #include "nsIMsgIncomingServer.h"
 #include "nsIRssIncomingServer.h"
 #include "nsIMsgHdr.h"
@@ -148,48 +146,40 @@ nsresult nsMsgContentPolicy::AllowRemote
 
   nsCOMPtr<nsIMsgHeaderParser> headerParser = do_GetService("@mozilla.org/messenger/headerparser;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCString emailAddress; 
   rv = headerParser->ExtractHeaderAddressMailboxes(nsnull, author.get(), getter_Copies(emailAddress));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!mCachedTopLevelAb)
-  {
-    // Use the RDF service to walk through the list of local directories
-    nsCOMPtr<nsIRDFService> rdfService =
-      do_GetService("@mozilla.org/rdf/rdf-service;1", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsCOMPtr<nsIRDFResource> resource;
-    rv = rdfService->GetResource(NS_LITERAL_CSTRING("moz-abdirectory://"),
-                                 getter_AddRefs(resource));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    mCachedTopLevelAb = do_QueryInterface(resource, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
+  nsCOMPtr<nsIAbManager> abManager = do_GetService("@mozilla.org/abmanager;1",
+                                                   &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISimpleEnumerator> enumerator;
-  rv = mCachedTopLevelAb->GetChildNodes(getter_AddRefs(enumerator));
+  rv = abManager->GetDirectories(getter_AddRefs(enumerator));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISupports> supports;
-  nsCOMPtr<nsIAbMDBDirectory> mdbDirectory;
+  nsCOMPtr<nsIAbDirectory> directory;
   nsCOMPtr<nsIAbCard> cardForAddress;
   PRBool hasMore;
 
   while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore && !cardForAddress)
   {
     rv = enumerator->GetNext(getter_AddRefs(supports));
     NS_ENSURE_SUCCESS(rv, rv);
-    mdbDirectory = do_QueryInterface(supports);
-    if (mdbDirectory)
-      mdbDirectory->CardForEmailAddress(emailAddress, getter_AddRefs(cardForAddress));
+    directory = do_QueryInterface(supports);
+    if (directory)
+    {
+      rv = directory->CardForEmailAddress(emailAddress, getter_AddRefs(cardForAddress));
+      if (NS_FAILED(rv) && rv != NS_ERROR_NOT_IMPLEMENTED)
+        return rv;
+    }
   }
   
   // if we found a card from the sender, 
   if (cardForAddress)
     cardForAddress->GetPropertyAsBool(kAllowRemoteContentProperty, aAllowForSender);
 
   return NS_OK;
 }
--- a/mailnews/base/src/nsMsgContentPolicy.h
+++ b/mailnews/base/src/nsMsgContentPolicy.h
@@ -45,17 +45,16 @@
 
 #ifndef _nsMsgContentPolicy_H_
 #define _nsMsgContentPolicy_H_
 
 #include "nsIContentPolicy.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsString.h"
-#include "nsIAbDirectory.h"
 
 #include "nsICookiePermission.h" 
 
 /* DBFCFDF0-4489-4faa-8122-190FD1EFA16C */
 #define NS_MSGCONTENTPOLICY_CID \
 { 0xdbfcfdf0, 0x4489, 0x4faa, { 0x81, 0x22, 0x19, 0xf, 0xd1, 0xef, 0xa1, 0x6c } }
 
 #define NS_MSGCONTENTPOLICY_CONTRACTID "@mozilla.org/messenger/content-policy;1"
@@ -76,17 +75,16 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSICONTENTPOLICY
   NS_DECL_NSIOBSERVER
 
 protected:
   PRBool   mBlockRemoteImages;
   PRBool   mAllowPlugins;
   nsCString mTrustedMailDomains;
-  nsCOMPtr<nsIAbDirectory> mCachedTopLevelAb;
 
   PRBool IsTrustedDomain(nsIURI * aContentLocation);
   nsresult AllowRemoteContentForSender(nsIMsgDBHdr * aMsgHdr, PRBool * aAllowForSender);
   nsresult AllowRemoteContentForMsgHdr(nsIMsgDBHdr * aMsgHdr, nsIURI * aRequestingLocation, nsIURI * aContentLocation, PRInt16 *aDecision);
   nsresult MailShouldLoad(nsIURI * aRequestingLocation, nsIURI * aContentLocation, PRInt16 * aDecision);
   nsresult ComposeShouldLoad(nsIDocShell * aRootDocShell, nsISupports *aRequestingContext, 
                              nsIURI * aContentLocation, PRInt16 * aDecision);
 
--- a/mailnews/base/util/nsMsgDBFolder.cpp
+++ b/mailnews/base/util/nsMsgDBFolder.cpp
@@ -60,17 +60,17 @@
 #include "nsIPrompt.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILocale.h"
 #include "nsILocaleService.h"
 #include "nsCollationCID.h"
 #include "nsAbBaseCID.h"
 #include "nsIAbCard.h"
-#include "nsIAbMDBDirectory.h"
+#include "nsIAbDirectory.h"
 #include "nsISpamSettings.h"
 #include "nsIMsgFilterPlugin.h"
 #include "nsIMsgMailSession.h"
 #include "nsIRDFService.h"
 #include "nsTextFormatter.h"
 #include "nsCPasswordManager.h"
 #include "nsMsgDBCID.h"
 #include "nsInt64.h"
@@ -1771,17 +1771,17 @@ nsMsgDBFolder::SpamFilterClassifyMessage
  */
 NS_IMETHODIMP
 nsMsgDBFolder::CallFilterPlugins(nsIMsgWindow *aMsgWindow, PRBool *aFiltersRun)
 {
   NS_ENSURE_ARG_POINTER(aFiltersRun);
   *aFiltersRun = PR_FALSE;
   nsCOMPtr<nsIMsgIncomingServer> server;
   nsCOMPtr<nsISpamSettings> spamSettings;
-  nsCOMArray<nsIAbMDBDirectory> whiteListDirArray;
+  nsCOMArray<nsIAbDirectory> whiteListDirArray;
   nsCOMPtr<nsIMsgHeaderParser> headerParser;
   PRBool useWhiteList = PR_FALSE;
   PRInt32 spamLevel = 0;
   nsCString whiteListAbURI;
 
   nsresult rv = GetServer(getter_AddRefs(server));
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1871,17 +1871,18 @@ nsMsgDBFolder::CallFilterPlugins(nsIMsgW
       nsCStringArray whiteListArray;
       whiteListArray.ParseString(whiteListAbURI.get(), " ");
 
       for (PRInt32 index = 0; index < whiteListArray.Count(); index++)
       {
         nsCOMPtr<nsIRDFResource> resource;
         rv = rdfService->GetResource(*whiteListArray[index], getter_AddRefs(resource));
 
-        nsCOMPtr<nsIAbMDBDirectory> whiteListDirectory = do_QueryInterface(resource, &rv);
+        nsCOMPtr<nsIAbDirectory> whiteListDirectory =
+          do_QueryInterface(resource, &rv);
         if (whiteListDirectory)
           whiteListDirArray.AppendObject(whiteListDirectory);
       }
     }
     // if we can't get the db, we probably want to continue firing spam filters.
   }
 
   nsCString trustedMailDomains;
@@ -1940,19 +1941,18 @@ nsMsgDBFolder::CallFilterPlugins(nsIMsgW
     {
       if (NS_SUCCEEDED(rv))
       {
         nsIAbCard* cardForAddress = nsnull;
         // don't want to abort the rest of the scoring.
         if (!authorEmailAddress.IsEmpty())
         {
           for (PRInt32 index = 0; index < whiteListDirArray.Count() && !cardForAddress; index++)
-            rv = whiteListDirArray[index]->CardForEmailAddress(authorEmailAddress, &cardForAddress);
-            if (NS_FAILED(rv))
-              cardForAddress = nsnull;
+            whiteListDirArray[index]->CardForEmailAddress(authorEmailAddress,
+                                                          &cardForAddress);
         }
         if (cardForAddress)
         {
           NS_RELEASE(cardForAddress);
           // mark this msg as non-junk, because we whitelisted it.
           mDatabase->SetStringProperty(msgKey, "junkscore", "0");
           mDatabase->SetStringProperty(msgKey, "junkscoreorigin", "whitelist");
           continue; // skip this msg since it's in the white list