Back to index

lightning-sunbird  0.9+nobinonly
nsAbBSDirectory.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Paul Sandoz   <paul.sandoz@sun.com>
00024  *   Csaba Borbola <csaba.borbola@sun.com>
00025  *   Seth Spitzer <sspitzer@netscape.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #include "nsIPrefService.h"
00042 #include "nsAbBSDirectory.h"
00043 
00044 #include "nsRDFCID.h"
00045 #include "nsIRDFService.h"
00046 
00047 #include "nsDirPrefs.h"
00048 #include "nsAbBaseCID.h"
00049 #include "nsMsgBaseCID.h"
00050 #include "nsIAddressBook.h"
00051 #include "nsAddrDatabase.h"
00052 #include "nsIAddrBookSession.h"
00053 #include "nsIAbMDBDirectory.h"
00054 #include "nsIAbUpgrader.h"
00055 #include "nsIMessengerMigrator.h"
00056 #include "nsAbDirFactoryService.h"
00057 #include "nsAbMDBDirFactory.h"
00058 #include "nsArrayEnumerator.h"
00059 
00060 nsAbBSDirectory::nsAbBSDirectory()
00061 : nsRDFResource(),
00062 mInitialized(PR_FALSE),
00063 mServers (13)
00064 {
00065 }
00066 
00067 nsAbBSDirectory::~nsAbBSDirectory()
00068 {
00069 }
00070 
00071 NS_IMPL_ISUPPORTS_INHERITED1(nsAbBSDirectory, nsRDFResource, nsIAbDirectory)
00072 
00073 nsresult nsAbBSDirectory::CreateDirectoriesFromFactory(
00074                                                        nsIAbDirectoryProperties *aProperties,
00075                                                        DIR_Server *aServer,
00076                                                        PRBool aNotify)
00077 {
00078   nsresult rv;
00079   NS_ENSURE_ARG_POINTER(aProperties);
00080   
00081   // Get the directory factory service
00082   nsCOMPtr<nsIAbDirFactoryService> dirFactoryService = 
00083     do_GetService(NS_ABDIRFACTORYSERVICE_CONTRACTID,&rv);
00084   NS_ENSURE_SUCCESS (rv, rv);
00085               
00086   // Get the directory factory from the URI
00087   nsXPIDLCString uri;
00088   rv = aProperties->GetURI(getter_Copies(uri));
00089   NS_ENSURE_SUCCESS(rv,rv);
00090   
00091   nsCOMPtr<nsIAbDirFactory> dirFactory;
00092   rv = dirFactoryService->GetDirFactory(uri.get(), getter_AddRefs(dirFactory));
00093   NS_ENSURE_SUCCESS (rv, rv);
00094   
00095   // Create the directories
00096   nsCOMPtr<nsISimpleEnumerator> newDirEnumerator;
00097   rv = dirFactory->CreateDirectory(aProperties, getter_AddRefs(newDirEnumerator));
00098   NS_ENSURE_SUCCESS (rv, rv);
00099   
00100   // Enumerate through the directories adding them
00101   // to the sub directories array
00102   PRBool hasMore;
00103   nsCOMPtr<nsIAddrBookSession> abSession = 
00104     do_GetService(NS_ADDRBOOKSESSION_CONTRACTID, &rv); 
00105 
00106   while (NS_SUCCEEDED(newDirEnumerator->HasMoreElements(&hasMore)) && hasMore)
00107   {
00108     nsCOMPtr<nsISupports> newDirSupports;
00109     rv = newDirEnumerator->GetNext(getter_AddRefs(newDirSupports));
00110     if(NS_FAILED(rv))
00111       continue;
00112     
00113     nsCOMPtr<nsIAbDirectory> childDir = do_QueryInterface(newDirSupports, &rv); 
00114     if(NS_FAILED(rv))
00115       continue;
00116     
00117     // Define a relationship between the preference
00118     // entry and the directory
00119     nsVoidKey key((void *)childDir);
00120     mServers.Put (&key, (void *)aServer);
00121     
00122     mSubDirectories.AppendObject(childDir);
00123     
00124     // Inform the listener, i.e. the RDF directory data
00125     // source that a new address book has been added
00126     if (aNotify && abSession)
00127       abSession->NotifyDirectoryItemAdded(this, childDir);
00128   }
00129   
00130   return NS_OK;
00131 }
00132 
00133 NS_IMETHODIMP nsAbBSDirectory::GetChildNodes(nsISimpleEnumerator* *aResult)
00134 {
00135   if (!mInitialized) 
00136   {
00137     nsresult rv;
00138     nsCOMPtr<nsIAbDirFactoryService> dirFactoryService = 
00139       do_GetService(NS_ABDIRFACTORYSERVICE_CONTRACTID,&rv);
00140     NS_ENSURE_SUCCESS (rv, rv);
00141     
00142     nsVoidArray *directories = DIR_GetDirectories();
00143     if (!directories)
00144       return NS_ERROR_FAILURE;
00145     
00146     PRInt32 count = directories->Count();
00147     for (PRInt32 i = 0; i < count; i++)
00148     {
00149       DIR_Server *server = (DIR_Server *)(directories->ElementAt(i));
00150       
00151       // if this is a 4.x, local .na2 addressbook (PABDirectory)
00152       // we must skip it.
00153       // mozilla can't handle 4.x .na2 addressbooks
00154       // note, the filename might be na2 for 4.x LDAP directories
00155       // (we used the .na2 file for replication), and we don't want to skip
00156       // those.  see bug #127007
00157       PRUint32 fileNameLen = strlen(server->fileName);
00158       if (((fileNameLen > kABFileName_PreviousSuffixLen) && 
00159         strcmp(server->fileName + fileNameLen - kABFileName_PreviousSuffixLen, kABFileName_PreviousSuffix) == 0) &&
00160         (server->dirType == PABDirectory))
00161         continue;
00162       
00163       nsCOMPtr<nsIAbDirectoryProperties> properties(do_CreateInstance(NS_ABDIRECTORYPROPERTIES_CONTRACTID, &rv));
00164       NS_ENSURE_SUCCESS(rv,rv);
00165       
00166       NS_ConvertUTF8toUCS2 description (server->description);
00167       rv = properties->SetDescription(description);
00168       NS_ENSURE_SUCCESS(rv,rv);
00169       
00170       rv = properties->SetFileName(server->fileName);
00171       NS_ENSURE_SUCCESS(rv,rv);
00172       
00173       // Set the uri property
00174       nsCAutoString URI (server->uri);
00175       // This is in case the uri is never set
00176       // in the nsDirPref.cpp code.
00177       if (!server->uri)
00178         URI = NS_LITERAL_CSTRING(kMDBDirectoryRoot) + nsDependentCString(server->fileName);
00179       
00180       /*
00181       * Check that we are not converting from a
00182       * a 4.x address book file e.g. pab.na2
00183       * check if the URI ends with ".na2"
00184       */
00185       if (StringEndsWith(URI, NS_LITERAL_CSTRING(kABFileName_PreviousSuffix))) 
00186         URI.ReplaceSubstring(URI.get() + kMDBDirectoryRootLen, server->fileName);
00187       
00188       rv = properties->SetPrefName(server->prefName);
00189       NS_ENSURE_SUCCESS(rv,rv);
00190       
00191       rv = properties->SetURI(URI.get());
00192       NS_ENSURE_SUCCESS(rv,rv);
00193       
00194       // Create the directories
00195       rv = CreateDirectoriesFromFactory(properties,
00196         server, PR_FALSE /* notify */);
00197     }
00198     
00199     mInitialized = PR_TRUE;
00200     // sort directories by position...
00201   }
00202   return NS_NewArrayEnumerator(aResult, mSubDirectories);
00203 }
00204 
00205 NS_IMETHODIMP nsAbBSDirectory::CreateNewDirectory(nsIAbDirectoryProperties *aProperties)
00206 {
00207 /*
00208 * TODO
00209 * This procedure is still MDB specific
00210 * due to the dependence on the current
00211 * nsDirPref.cpp code
00212 *
00213         */
00214   NS_ENSURE_ARG_POINTER(aProperties);
00215   nsresult rv;
00216   
00217   nsAutoString description;
00218   nsXPIDLCString fileName;
00219   nsXPIDLCString uri;
00220   nsXPIDLCString authDn;
00221   
00222   rv = aProperties->GetDescription(description);
00223   NS_ENSURE_SUCCESS(rv, rv);
00224   
00225   rv = aProperties->GetFileName(getter_Copies(fileName));
00226   NS_ENSURE_SUCCESS(rv, rv);
00227   
00228   rv = aProperties->GetURI(getter_Copies(uri));
00229   NS_ENSURE_SUCCESS(rv, rv);
00230   
00231   PRUint32 dirType;
00232   rv = aProperties->GetDirType(&dirType);
00233   NS_ENSURE_SUCCESS(rv, rv);
00234   
00235   PRUint32 maxHits;
00236   rv = aProperties->GetMaxHits(&maxHits);
00237   NS_ENSURE_SUCCESS(rv, rv);
00238   
00239   rv = aProperties->GetAuthDn(getter_Copies(authDn));
00240   NS_ENSURE_SUCCESS(rv, rv);
00241   
00242   /*
00243    * The creation of the address book in the preferences
00244    * is very MDB implementation specific.
00245    * If the fileName attribute is null then it will
00246    * create an appropriate file name.
00247    * Somehow have to resolve this issue so that it
00248    * is more general.
00249    *
00250    */
00251   DIR_Server* server = nsnull;
00252   rv = DIR_AddNewAddressBook(description.get(),
00253     (fileName.Length ()) ? fileName.get () : nsnull,
00254     PR_FALSE /* is_migrating */, uri.get(),
00255     maxHits, authDn,
00256     (DirectoryType)dirType, 
00257     &server);
00258   NS_ENSURE_SUCCESS (rv, rv);
00259   
00260   // Update the file name property
00261   rv = aProperties->SetFileName(server->fileName);
00262   NS_ENSURE_SUCCESS(rv, rv);
00263   
00264   if (dirType != LDAPDirectory) {
00265     // Add the URI property
00266     nsCAutoString URI(NS_LITERAL_CSTRING(kMDBDirectoryRoot) + nsDependentCString(server->fileName));
00267     rv = aProperties->SetURI(URI.get());
00268     NS_ENSURE_SUCCESS(rv, rv);
00269   }
00270   
00271   rv = aProperties->SetPrefName(server->prefName);
00272   NS_ENSURE_SUCCESS(rv, rv);
00273   
00274   rv = CreateDirectoriesFromFactory(aProperties, server, PR_TRUE /* notify */);
00275   NS_ENSURE_SUCCESS(rv,rv);
00276   return rv;
00277 }
00278 
00279 NS_IMETHODIMP nsAbBSDirectory::CreateDirectoryByURI(const PRUnichar *aDisplayName, const char *aURI, PRBool migrating)
00280 {
00281   NS_ENSURE_ARG_POINTER(aURI);
00282   NS_ENSURE_ARG_POINTER(aDisplayName);
00283 
00284   nsresult rv = NS_OK;
00285 
00286   const char* fileName = nsnull;
00287   if (StringBeginsWith(nsDependentCString(aURI), NS_LITERAL_CSTRING(kMDBDirectoryRoot)))
00288     fileName = aURI + kMDBDirectoryRootLen;
00289 
00290   DIR_Server * server = nsnull;
00291   rv = DIR_AddNewAddressBook(aDisplayName, fileName, migrating, aURI, 0, nsnull, PABDirectory, &server);
00292   NS_ENSURE_SUCCESS(rv,rv);
00293 
00294   nsCOMPtr <nsIAbDirectoryProperties> properties;
00295   properties = do_CreateInstance(NS_ABDIRECTORYPROPERTIES_CONTRACTID, &rv);
00296   NS_ENSURE_SUCCESS(rv,rv);
00297 
00298   rv = properties->SetDescription(nsDependentString(aDisplayName));
00299   NS_ENSURE_SUCCESS(rv,rv);
00300        
00301   rv = properties->SetFileName(server->fileName);
00302   NS_ENSURE_SUCCESS(rv,rv);
00303 
00304   rv = properties->SetURI(aURI);
00305   NS_ENSURE_SUCCESS(rv,rv);
00306 
00307   rv = properties->SetPrefName(server->prefName);
00308   NS_ENSURE_SUCCESS(rv,rv);
00309 
00310   rv = properties->SetDirType(server->dirType);
00311   NS_ENSURE_SUCCESS(rv,rv);
00312 
00313   rv = CreateDirectoriesFromFactory(properties, server, PR_TRUE /* notify */);
00314   NS_ENSURE_SUCCESS(rv,rv);
00315        return rv;
00316 }
00317 
00318 struct GetDirectories
00319 {
00320   GetDirectories (DIR_Server* aServer) :
00321   mServer (aServer)
00322   {
00323     NS_NewISupportsArray(getter_AddRefs(directories));
00324   }
00325 
00326   nsCOMPtr<nsISupportsArray> directories;
00327   DIR_Server* mServer;
00328 };
00329 
00330 PRBool PR_CALLBACK GetDirectories_getDirectory (nsHashKey *aKey, void *aData, void* closure)
00331 {
00332        GetDirectories* getDirectories = (GetDirectories* )closure;
00333 
00334        DIR_Server* server = (DIR_Server*) aData;
00335        if (server == getDirectories->mServer)
00336        {
00337                      nsVoidKey* voidKey = (nsVoidKey* )aKey;
00338                      nsIAbDirectory* directory = (nsIAbDirectory* )voidKey->GetValue ();
00339                      getDirectories->directories->AppendElement (directory);
00340        }
00341 
00342        return PR_TRUE;
00343 }
00344 
00345 NS_IMETHODIMP nsAbBSDirectory::DeleteDirectory(nsIAbDirectory *directory)
00346 {
00347        nsresult rv;
00348        
00349        NS_ENSURE_ARG_POINTER(directory);
00350 
00351        // if addressbook is not launched yet mSevers will not be initialized
00352        // calling GetChildNodes will initialize mServers
00353        if (!mInitialized) {
00354               nsCOMPtr<nsISimpleEnumerator> subDirectories;
00355               rv = GetChildNodes(getter_AddRefs(subDirectories));
00356               NS_ENSURE_SUCCESS(rv, rv);
00357        }
00358 
00359        nsVoidKey key((void *)directory);
00360        DIR_Server *server = (DIR_Server* )mServers.Get (&key);
00361 
00362        if (!server)
00363               return NS_ERROR_FAILURE;
00364 
00365        GetDirectories getDirectories (server);
00366        mServers.Enumerate (GetDirectories_getDirectory, (void *)&getDirectories);
00367 
00368        DIR_DeleteServerFromList(server);
00369        
00370        nsCOMPtr<nsIAbDirFactoryService> dirFactoryService = 
00371                      do_GetService(NS_ABDIRFACTORYSERVICE_CONTRACTID,&rv);
00372        NS_ENSURE_SUCCESS (rv, rv);
00373 
00374        PRUint32 count;
00375        rv = getDirectories.directories->Count (&count);
00376        NS_ENSURE_SUCCESS(rv, rv);
00377 
00378   nsCOMPtr<nsIAddrBookSession> abSession =
00379     do_GetService(NS_ADDRBOOKSESSION_CONTRACTID);
00380   
00381        for (PRUint32 i = 0; i < count; i++)
00382        {
00383               nsCOMPtr<nsIAbDirectory> d;
00384               getDirectories.directories->GetElementAt (i, getter_AddRefs(d));
00385 
00386               nsVoidKey k((void *)d);
00387               mServers.Remove(&k);
00388 
00389               rv = mSubDirectories.RemoveObject(d);
00390 
00391     if (abSession)
00392       abSession->NotifyDirectoryDeleted(this, d);
00393 
00394               nsCOMPtr<nsIRDFResource> resource (do_QueryInterface (d, &rv));
00395               const char* uri;
00396               resource->GetValueConst (&uri);
00397 
00398               nsCOMPtr<nsIAbDirFactory> dirFactory;
00399               rv = dirFactoryService->GetDirFactory (uri, getter_AddRefs(dirFactory));
00400               if (NS_FAILED(rv))
00401                             continue;
00402 
00403               rv = dirFactory->DeleteDirectory(d);
00404        }
00405 
00406        return rv;
00407 }
00408 
00409 NS_IMETHODIMP nsAbBSDirectory::ModifyDirectory(nsIAbDirectory *directory, nsIAbDirectoryProperties *aProperties)
00410 {
00411   nsresult rv;
00412 
00413   NS_ENSURE_ARG_POINTER(directory);
00414   NS_ENSURE_ARG_POINTER(aProperties);
00415 
00416   // if addressbook is not launched yet mSevers will not be initialized
00417   // calling GetChildNodes will initialize mServers
00418   if (!mInitialized) {
00419     nsCOMPtr<nsISimpleEnumerator> subDirectories;
00420     rv = GetChildNodes(getter_AddRefs(subDirectories));
00421     NS_ENSURE_SUCCESS(rv, rv);
00422   }
00423 
00424   nsVoidKey key((void *)directory);
00425   DIR_Server *server = (DIR_Server* )mServers.Get(&key);
00426 
00427   if (!server)
00428     return NS_ERROR_FAILURE;
00429   GetDirectories getDirectories (server);
00430   mServers.Enumerate (GetDirectories_getDirectory, (void *)&getDirectories);
00431 
00432   nsAutoString description;
00433   nsXPIDLCString uri;
00434   nsXPIDLCString authDn;
00435   PRUint32 maxHits, palmSyncTimeStamp;
00436   PRInt32 palmCategoryId;
00437 
00438   rv = aProperties->GetDescription(description);
00439   NS_ENSURE_SUCCESS(rv, rv);
00440  
00441   NS_ConvertUTF8toUCS2 oldValue(server->description);
00442   nsCRT::free(server->description);
00443   NS_ConvertUCS2toUTF8 utf8str(description.get());
00444   server->description = ToNewCString(utf8str);
00445 
00446   rv = aProperties->GetURI(getter_Copies(uri));
00447   NS_ENSURE_SUCCESS(rv, rv);
00448   nsCRT::free(server->uri);
00449   server->uri = ToNewCString(uri);
00450 
00451   rv = aProperties->GetMaxHits(&maxHits);
00452   NS_ENSURE_SUCCESS(rv, rv);
00453   server->maxHits = maxHits;
00454   
00455   rv = aProperties->GetAuthDn(getter_Copies(authDn));
00456   NS_ENSURE_SUCCESS(rv, rv);
00457   nsCRT::free(server->authDn);
00458   server->authDn = ToNewCString(authDn);
00459 
00460   rv = aProperties->GetSyncTimeStamp(&palmSyncTimeStamp);
00461   NS_ENSURE_SUCCESS(rv, rv);
00462   server->PalmSyncTimeStamp = palmSyncTimeStamp;
00463 
00464   rv = aProperties->GetCategoryId(&palmCategoryId);
00465   NS_ENSURE_SUCCESS(rv, rv);
00466   server->PalmCategoryId = palmCategoryId;
00467   
00468   DIR_SavePrefsForOneServer(server);
00469 
00470   if (!oldValue.Equals(description)) {
00471     nsCOMPtr<nsIAbDirectory> modifiedDir;
00472     getDirectories.directories->GetElementAt (0, getter_AddRefs(modifiedDir));
00473 
00474     // First tell the directory it's new name
00475     rv = modifiedDir->SetDirName(description.get());
00476     NS_ENSURE_SUCCESS(rv, rv);
00477 
00478     // Then tell everyone else.
00479     nsCOMPtr<nsIAddrBookSession> abSession = 
00480               do_GetService(NS_ADDRBOOKSESSION_CONTRACTID, &rv);
00481 
00482     if (NS_SUCCEEDED(rv))
00483       abSession->NotifyItemPropertyChanged(modifiedDir, "DirName", oldValue.get(), description.get());
00484   }
00485 
00486   // Save modified address book into pref file.
00487   nsCOMPtr<nsIPrefService> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); 
00488   NS_ENSURE_SUCCESS(rv, rv);
00489   return prefService->SavePrefFile(nsnull);
00490 }
00491 
00492 NS_IMETHODIMP nsAbBSDirectory::HasDirectory(nsIAbDirectory *dir, PRBool *hasDir)
00493 {
00494   if (!hasDir)
00495     return NS_ERROR_NULL_POINTER;
00496   
00497   nsVoidKey key((void *)dir);
00498   DIR_Server *dirServer = (DIR_Server* )mServers.Get (&key);
00499   return DIR_ContainsServer(dirServer, hasDir);
00500 }
00501