Back to index

lightning-sunbird  0.9+nobinonly
nsAbLDAPReplicationData.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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  * Rajiv Dayal <rdayal@netscape.com>
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *  Dan Mosedale <dan.mosedale@oracle.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsILDAPMessage.h"
00040 #include "nsAbLDAPReplicationData.h"
00041 #include "nsLDAP.h"
00042 #include "nsIAbCard.h"
00043 #include "nsIAddrBookSession.h"
00044 #include "nsAbBaseCID.h"
00045 #include "nsAbUtils.h"
00046 #include "nsIAbMDBCard.h"
00047 #include "nsAbLDAPReplicationQuery.h"
00048 #include "nsProxiedService.h"
00049 #include "nsCPasswordManager.h"
00050 #include "nsIRDFService.h"
00051 #include "nsIRDFResource.h"
00052 
00053 // once bug # 101252 gets fixed, this should be reverted back to be non threadsafe
00054 // implementation is not really thread safe since each object should exist 
00055 // independently along with its related independent nsAbLDAPReplicationQuery object.
00056 NS_IMPL_THREADSAFE_ISUPPORTS2(nsAbLDAPProcessReplicationData, nsIAbLDAPProcessReplicationData, nsILDAPMessageListener)
00057 
00058 nsAbLDAPProcessReplicationData::nsAbLDAPProcessReplicationData()
00059  : mState(kIdle),
00060    mProtocol(-1),
00061    mCount(0),
00062    mDBOpen(PR_FALSE),
00063    mInitialized(PR_FALSE),
00064    mDirServerInfo(nsnull)
00065 {
00066 }
00067 
00068 nsAbLDAPProcessReplicationData::~nsAbLDAPProcessReplicationData()
00069 {
00070   /* destructor code */
00071   if(mDBOpen && mReplicationDB) 
00072       mReplicationDB->Close(PR_FALSE);
00073 }
00074 
00075 NS_IMETHODIMP nsAbLDAPProcessReplicationData::Init(nsIAbLDAPReplicationQuery *query, nsIWebProgressListener *progressListener)
00076 {
00077    NS_ENSURE_ARG_POINTER(query);
00078 
00079    mQuery = query;
00080 
00081    nsresult rv = mQuery->GetReplicationServerInfo(&mDirServerInfo);
00082    if(NS_FAILED(rv)) {
00083        mQuery = nsnull;
00084        return rv;   
00085    }
00086    if(!mDirServerInfo) {
00087        mQuery = nsnull;
00088        return NS_ERROR_FAILURE;   
00089    }
00090 
00091    nsCOMPtr<nsIAbLDAPAttributeMapService> mapSvc = 
00092        do_GetService("@mozilla.org/addressbook/ldap-attribute-map-service;1",
00093                      &rv);
00094    NS_ENSURE_SUCCESS(rv, rv);
00095 
00096    rv = mapSvc->GetMapForPrefBranch(
00097        nsDependentCString(mDirServerInfo->prefName), getter_AddRefs(mAttrMap));
00098    NS_ENSURE_SUCCESS(rv, rv);
00099 
00100    mListener = progressListener;
00101 
00102    mInitialized = PR_TRUE;
00103 
00104    return rv;
00105 }
00106 
00107 NS_IMETHODIMP nsAbLDAPProcessReplicationData::GetReplicationState(PRInt32 *aReplicationState) 
00108 {
00109     NS_ENSURE_ARG_POINTER(aReplicationState);
00110 
00111     *aReplicationState = mState; 
00112     return NS_OK; 
00113 }
00114 
00115 NS_IMETHODIMP nsAbLDAPProcessReplicationData::GetProtocolUsed(PRInt32 *aProtocolUsed) 
00116 {
00117     NS_ENSURE_ARG_POINTER(aProtocolUsed);
00118     *aProtocolUsed = mProtocol; 
00119     return NS_OK; 
00120 }
00121 
00122 NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPInit(nsILDAPConnection *aConn, nsresult aStatus)
00123 {
00124     if(!mInitialized) 
00125         return NS_ERROR_NOT_INITIALIZED;
00126 
00127     // Make sure that the Init() worked properly
00128     if(NS_FAILED(aStatus)) {
00129         Done(PR_FALSE);
00130         return NS_ERROR_FAILURE;
00131     }
00132 
00133     nsCOMPtr<nsILDAPMessageListener> listener;
00134     nsresult rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ,
00135                   NS_GET_IID(nsILDAPMessageListener), 
00136                   NS_STATIC_CAST(nsILDAPMessageListener*, this),
00137                   PROXY_SYNC | PROXY_ALWAYS, 
00138                   getter_AddRefs(listener));
00139     if(NS_FAILED(rv)) {
00140         Done(PR_FALSE);
00141         return rv;
00142     }
00143 
00144     nsCOMPtr<nsILDAPOperation> operation;
00145     rv = mQuery->GetOperation(getter_AddRefs(operation));
00146     if(NS_FAILED(rv)) {
00147        Done(PR_FALSE);
00148        return rv;   
00149     }
00150 
00151     nsCOMPtr<nsILDAPConnection> connection;
00152     rv = mQuery->GetConnection(getter_AddRefs(connection));
00153     if(NS_FAILED(rv)) {
00154        Done(PR_FALSE);
00155        return rv;  
00156     }
00157 
00158     rv = operation->Init(connection, listener, nsnull);
00159     if(NS_FAILED(rv)) {
00160         Done(PR_FALSE);
00161         return rv;
00162     }
00163 
00164     // Bind
00165     rv = operation->SimpleBind(mAuthPswd);
00166     mState = mAuthPswd.IsEmpty() ? kAnonymousBinding : kAuthenticatedBinding;
00167 
00168     if(NS_FAILED(rv)) {
00169         Done(PR_FALSE);
00170     }
00171 
00172     return rv;
00173 }
00174 
00175 NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPMessage(nsILDAPMessage *aMessage)
00176 {
00177     NS_ENSURE_ARG_POINTER(aMessage);
00178     if(!mInitialized) 
00179         return NS_ERROR_NOT_INITIALIZED;
00180 
00181     PRInt32 messageType;
00182     nsresult rv = aMessage->GetType(&messageType);
00183     if(NS_FAILED(rv)) {
00184 #ifdef DEBUG_rdayal
00185         printf("LDAP Replication : OnLDAPMessage : couldnot GetType \n");
00186 #endif
00187         Done(PR_FALSE);
00188         return rv;
00189     }
00190 
00191     switch(messageType)
00192     {
00193     case nsILDAPMessage::RES_BIND:
00194         rv = OnLDAPBind(aMessage);
00195         break;
00196     case nsILDAPMessage::RES_SEARCH_ENTRY:
00197         rv = OnLDAPSearchEntry(aMessage);
00198         break;
00199     case nsILDAPMessage::RES_SEARCH_RESULT:
00200         rv = OnLDAPSearchResult(aMessage);
00201         break;
00202     default:
00203         // for messageTypes we do not handle return NS_OK to LDAP and move ahead.
00204         rv = NS_OK;
00205         break;
00206     }
00207 
00208     return rv;
00209 }
00210 
00211 NS_IMETHODIMP nsAbLDAPProcessReplicationData::Abort()
00212 {
00213     if(!mInitialized) 
00214         return NS_ERROR_NOT_INITIALIZED;
00215 
00216 #ifdef DEBUG_rdayal
00217     printf ("ChangeLog Replication : ABORT called !!! \n");
00218 #endif
00219 
00220     nsCOMPtr<nsILDAPOperation> operation;
00221     nsresult rv = mQuery->GetOperation(getter_AddRefs(operation));
00222     if(operation && mState != kIdle)
00223     {
00224         rv = operation->AbandonExt();
00225         if(NS_SUCCEEDED(rv))
00226             mState = kIdle;
00227     }
00228 
00229     if(mReplicationDB && mDBOpen) {
00230         mReplicationDB->ForceClosed(); // force close since we need to delete the file.
00231         mDBOpen = PR_FALSE;
00232 
00233         // delete the unsaved replication file
00234         if(mReplicationFile) {
00235             rv = mReplicationFile->Remove(PR_FALSE);
00236             if(NS_SUCCEEDED(rv)) {
00237                 // now put back the backed up replicated file if aborted
00238                 if(mBackupReplicationFile && mDirServerInfo->replInfo) 
00239                     rv = mBackupReplicationFile->MoveToNative(nsnull, nsDependentCString(mDirServerInfo->replInfo->fileName));
00240             }
00241         }
00242     }
00243 
00244 
00245     Done(PR_FALSE);
00246 
00247     return rv;
00248 }
00249 
00250 // this should get the authDN from prefs and password from PswdMgr
00251 NS_IMETHODIMP nsAbLDAPProcessReplicationData::PopulateAuthData()
00252 {
00253     mAuthDN.Assign(mDirServerInfo->authDn);
00254 
00255     nsresult rv = NS_OK;
00256     nsCOMPtr <nsIPasswordManagerInternal> passwordMgrInt = do_GetService(NS_PASSWORDMANAGER_CONTRACTID, &rv);
00257     if(NS_SUCCEEDED(rv) && passwordMgrInt) {
00258         // Get the current server URI
00259         nsCOMPtr<nsILDAPURL> url;
00260         rv = mQuery->GetReplicationURL(getter_AddRefs(url));
00261         if (NS_FAILED(rv))
00262             return rv;
00263         nsCAutoString serverUri;
00264         rv = url->GetSpec(serverUri);
00265         if (NS_FAILED(rv)) 
00266             return rv;
00267 
00268         nsCAutoString hostFound;
00269         nsAutoString userNameFound;
00270         nsAutoString passwordFound;
00271 
00272         // Get password entry corresponding to the server URI we are passing in.
00273         rv = passwordMgrInt->FindPasswordEntry(serverUri, EmptyString(),
00274                                                EmptyString(), hostFound,
00275                                                userNameFound, passwordFound);
00276         if (NS_FAILED(rv))
00277             return rv;
00278 
00279         if (!passwordFound.IsEmpty())
00280             CopyUTF16toUTF8(passwordFound, mAuthPswd);
00281     }
00282 
00283     return rv;
00284 }
00285 
00286 nsresult nsAbLDAPProcessReplicationData::OnLDAPBind(nsILDAPMessage *aMessage)
00287 {
00288     NS_ENSURE_ARG_POINTER(aMessage);
00289     if(!mInitialized) 
00290         return NS_ERROR_NOT_INITIALIZED;
00291 
00292     PRInt32 errCode;
00293 
00294     nsresult rv = aMessage->GetErrorCode(&errCode);
00295     if(NS_FAILED(rv)) {
00296         Done(PR_FALSE);
00297         return rv;
00298     }
00299 
00300     if(errCode != nsILDAPErrors::SUCCESS) {
00301         Done(PR_FALSE);
00302         return NS_ERROR_FAILURE;
00303     }
00304 
00305     rv = OpenABForReplicatedDir(PR_TRUE);
00306     if(NS_FAILED(rv)) {
00307         // do not call done here since it is called by OpenABForReplicationDir
00308         return rv;
00309     }
00310 
00311     rv = mQuery->QueryAllEntries();
00312     if(NS_FAILED(rv)) {
00313         Done(PR_FALSE);
00314         return rv;
00315     }
00316 
00317     mState = kReplicatingAll;
00318 
00319     if(mListener && NS_SUCCEEDED(rv))
00320         mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_TRUE);
00321 
00322     return rv;
00323 }
00324 
00325 nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
00326 {
00327     NS_ENSURE_ARG_POINTER(aMessage);
00328     if(!mInitialized) 
00329         return NS_ERROR_NOT_INITIALIZED;
00330     // since this runs on the main thread and is single threaded, this will 
00331     // take care of entries returned by LDAP Connection thread after Abort.
00332     if(!mReplicationDB || !mDBOpen) 
00333         return NS_ERROR_FAILURE;
00334 
00335   nsresult rv = NS_OK;
00336 
00337   // Although we would may naturally create an nsIAbLDAPCard here, we don't
00338   // need to as we are writing this straight to the database, so just create
00339   // the database version instead.
00340   nsCOMPtr<nsIAbMDBCard> dbCard(do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv));
00341   if(NS_FAILED(rv)) {
00342     Abort();
00343     return rv;
00344   }
00345 
00346   nsCOMPtr<nsIAbCard> newCard(do_QueryInterface(dbCard, &rv));
00347   if(NS_FAILED(rv)) {
00348     Abort();
00349     return rv;
00350   }
00351 
00352     rv = mAttrMap->SetCardPropertiesFromLDAPMessage(aMessage, newCard);
00353     if (NS_FAILED(rv))
00354     {
00355         NS_WARNING("nsAbLDAPProcessReplicationData::OnLDAPSearchEntry"
00356            "No card properties could be set");
00357         // if some entries are bogus for us, continue with next one
00358         return NS_OK;
00359     }
00360 
00361 #ifdef DEBUG_rdayal
00362         nsXPIDLString firstName;
00363         rv = card.GetFirstName(getter_Copies(firstName));
00364         NS_ENSURE_SUCCESS(rv,rv);
00365         nsXPIDLString lastName;
00366         rv = card.GetLastName(getter_Copies(lastName));
00367         NS_ENSURE_SUCCESS(rv,rv);
00368         nsCAutoString name;
00369         name.AssignWithConversion(firstName);
00370         name.Append("  ");
00371         name.AppendWithConversion(lastName);
00372         printf("\n LDAPReplication :: got card #: %d, name: %s \n", mCount, name.get());
00373 #endif
00374 
00375     rv = mReplicationDB->CreateNewCardAndAddToDB(newCard, PR_FALSE);
00376     if(NS_FAILED(rv)) {
00377         Abort();
00378         return rv;
00379     }
00380 
00381     // now set the attribute for the DN of the entry in the card in the DB
00382     nsCAutoString authDN;
00383     rv = aMessage->GetDn(authDN);
00384     if(NS_SUCCEEDED(rv) && !authDN.IsEmpty())
00385     {
00386         dbCard->SetAbDatabase(mReplicationDB);
00387         dbCard->SetStringAttribute("_DN", NS_ConvertUTF8toUCS2(authDN).get());
00388     }
00389 
00390     newCard = do_QueryInterface(dbCard, &rv);
00391     if(NS_FAILED(rv)) {
00392         Abort();
00393         return rv;
00394     }
00395 
00396     rv = mReplicationDB->EditCard(newCard, PR_FALSE);
00397     if(NS_FAILED(rv)) {
00398         Abort();
00399         return rv;
00400     }
00401     
00402 
00403     mCount ++;
00404 
00405     if(!(mCount % 10))  // inform the listener every 10 entries
00406     {
00407         mListener->OnProgressChange(nsnull,nsnull,mCount, -1, mCount, -1);
00408         // in case if the LDAP Connection thread is starved and causes problem
00409         // uncomment this one and try.
00410         // PR_Sleep(PR_INTERVAL_NO_WAIT); // give others a chance
00411     }
00412 
00413     return rv;
00414 }
00415 
00416 
00417 nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchResult(nsILDAPMessage *aMessage)
00418 {
00419 #ifdef DEBUG_rdayal
00420     printf("LDAP Replication : Got Results for Completion");
00421 #endif
00422 
00423     NS_ENSURE_ARG_POINTER(aMessage);
00424     if(!mInitialized) 
00425         return NS_ERROR_NOT_INITIALIZED;
00426 
00427     PRInt32 errorCode;
00428     nsresult rv = aMessage->GetErrorCode(&errorCode);
00429 
00430     if(NS_SUCCEEDED(rv)) {
00431         // We are done with the LDAP search for all entries.
00432         if(errorCode == nsILDAPErrors::SUCCESS || errorCode == nsILDAPErrors::SIZELIMIT_EXCEEDED) {
00433             Done(PR_TRUE);
00434             if(mReplicationDB && mDBOpen) {
00435                 rv = mReplicationDB->Close(PR_TRUE);
00436                 NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB Close on Success failed");
00437                 mDBOpen = PR_FALSE;
00438                 // once we have saved the new replication file, delete the backup file
00439                 if(mBackupReplicationFile)
00440                 {
00441                     rv = mBackupReplicationFile->Remove(PR_FALSE);
00442                     NS_ASSERTION(NS_SUCCEEDED(rv), "Replication BackupFile Remove on Success failed");
00443                 }
00444             }
00445             return NS_OK;
00446         }
00447     }
00448 
00449     // in case if GetErrorCode returned error or errorCode is not SUCCESS / SIZELIMIT_EXCEEDED
00450     if(mReplicationDB && mDBOpen) {
00451         // if error result is returned close the DB without saving ???
00452         // should we commit anyway ??? whatever is returned is not lost then !!
00453         rv = mReplicationDB->ForceClosed(); // force close since we need to delete the file.
00454         NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB ForceClosed on Failure failed");
00455         mDBOpen = PR_FALSE;
00456         // if error result is returned remove the replicated file
00457         if(mReplicationFile) {
00458             rv = mReplicationFile->Remove(PR_FALSE);
00459             NS_ASSERTION(NS_SUCCEEDED(rv), "Replication File Remove on Failure failed");
00460             if(NS_SUCCEEDED(rv)) {
00461                 // now put back the backed up replicated file
00462                 if(mBackupReplicationFile && mDirServerInfo->replInfo) 
00463                 {
00464                     rv = mBackupReplicationFile->MoveToNative(nsnull, nsDependentCString(mDirServerInfo->replInfo->fileName));
00465                     NS_ASSERTION(NS_SUCCEEDED(rv), "Replication Backup File Move back on Failure failed");
00466                 }
00467             }
00468         }
00469         Done(PR_FALSE);
00470     }
00471 
00472     return NS_OK;
00473 }
00474 
00475 nsresult nsAbLDAPProcessReplicationData::OpenABForReplicatedDir(PRBool aCreate)
00476 {
00477     if(!mInitialized) 
00478         return NS_ERROR_NOT_INITIALIZED;
00479 
00480     nsresult rv = NS_OK;
00481 
00482     nsCOMPtr<nsIAddrBookSession> abSession = do_GetService(NS_ADDRBOOKSESSION_CONTRACTID, &rv);
00483     if(NS_FAILED(rv)) {
00484         Done(PR_FALSE);
00485         return rv;
00486     }
00487 
00488     if(!mDirServerInfo->replInfo->fileName) {
00489         Done(PR_FALSE);
00490         return NS_ERROR_FAILURE;
00491     }
00492 
00493     rv = abSession->GetUserProfileDirectory(getter_AddRefs(mReplicationFile));
00494     if(NS_FAILED(rv)) {
00495         Done(PR_FALSE);
00496         return rv;
00497     }
00498 
00499     rv = mReplicationFile->AppendNative(nsDependentCString(mDirServerInfo->replInfo->fileName));
00500     if(NS_FAILED(rv)) {
00501         Done(PR_FALSE);
00502         return rv;
00503     }
00504 
00505     // if the AB DB already exists backup existing one, 
00506     // in case if the user cancels or Abort put back the backed up file
00507     PRBool fileExists;
00508     rv = mReplicationFile->Exists(&fileExists);
00509     if(NS_SUCCEEDED(rv) && fileExists) {
00510         // create the backup file object same as the Replication file object.
00511         // we create a backup file here since we need to cleanup the existing file
00512         // for create and then commit so instead of deleting existing cards we just
00513         // clone the existing one for a much better performance - for Download All.
00514         // And also important in case if replication fails we donot lose user's existing 
00515         // replicated data for both Download all and Changelog.
00516         nsCOMPtr<nsIFile> clone;
00517         rv = mReplicationFile->Clone(getter_AddRefs(clone));
00518         if(NS_FAILED(rv))  {
00519             Done(PR_FALSE);
00520             return rv;
00521         }
00522         mBackupReplicationFile = do_QueryInterface(clone, &rv);
00523         if(NS_FAILED(rv))  {
00524             Done(PR_FALSE);
00525             return rv;
00526         }
00527         rv = mBackupReplicationFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0777);
00528         if(NS_FAILED(rv))  {
00529             Done(PR_FALSE);
00530             return rv;
00531         }
00532         nsAutoString backupFileLeafName;
00533         rv = mBackupReplicationFile->GetLeafName(backupFileLeafName);
00534         if(NS_FAILED(rv))  {
00535             Done(PR_FALSE);
00536             return rv;
00537         }
00538         // remove the newly created unique backup file so that move and copy succeeds.
00539         rv = mBackupReplicationFile->Remove(PR_FALSE);
00540         if(NS_FAILED(rv))  {
00541             Done(PR_FALSE);
00542             return rv;
00543         }
00544 
00545         if(aCreate) {
00546             // set backup file to existing replication file for move
00547             mBackupReplicationFile->SetNativeLeafName(nsDependentCString(mDirServerInfo->replInfo->fileName));
00548             rv = mBackupReplicationFile->MoveTo(nsnull, backupFileLeafName);
00549             // set the backup file leaf name now
00550             if (NS_SUCCEEDED(rv))
00551                 mBackupReplicationFile->SetLeafName(backupFileLeafName);
00552         }
00553         else {
00554             // set backup file to existing replication file for copy
00555             mBackupReplicationFile->SetNativeLeafName(nsDependentCString(mDirServerInfo->replInfo->fileName));
00556             // specify the parent here specifically, 
00557             // passing nsnull to copy to the same dir actually renames existing file
00558             // instead of making another copy of the existing file.
00559             nsCOMPtr<nsIFile> parent;
00560             rv = mBackupReplicationFile->GetParent(getter_AddRefs(parent));
00561             if (NS_SUCCEEDED(rv))
00562                 rv = mBackupReplicationFile->CopyTo(parent, backupFileLeafName);
00563             // set the backup file leaf name now
00564             if (NS_SUCCEEDED(rv))
00565                 mBackupReplicationFile->SetLeafName(backupFileLeafName);
00566         }
00567         if(NS_FAILED(rv))  {
00568             Done(PR_FALSE);
00569             return rv;
00570         }
00571     }
00572 
00573     nsCOMPtr<nsIAddrDatabase> addrDBFactory = 
00574              do_GetService(NS_ADDRDATABASE_CONTRACTID, &rv);
00575     if(NS_FAILED(rv)) {
00576         if (mBackupReplicationFile)
00577             mBackupReplicationFile->Remove(PR_FALSE);
00578         Done(PR_FALSE);
00579         return rv;
00580     }
00581     
00582     rv = addrDBFactory->Open(mReplicationFile, aCreate, PR_TRUE, getter_AddRefs(mReplicationDB));
00583     if(NS_FAILED(rv)) {
00584         Done(PR_FALSE);
00585         if (mBackupReplicationFile)
00586             mBackupReplicationFile->Remove(PR_FALSE);
00587         return rv;
00588     }
00589 
00590     mDBOpen = PR_TRUE;  // replication DB is now Open
00591     return rv;
00592 }
00593 
00594 void nsAbLDAPProcessReplicationData::Done(PRBool aSuccess)
00595 {
00596    if(!mInitialized) 
00597        return;
00598 
00599    mState = kReplicationDone;
00600 
00601    mQuery->Done(aSuccess);
00602 
00603    if(mListener)
00604        mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_STOP, aSuccess);
00605 
00606    // since this is called when all is done here, either on success, failure or abort
00607    // releas the query now.
00608    mQuery = nsnull;
00609 }
00610 
00611 nsresult nsAbLDAPProcessReplicationData::DeleteCard(nsString & aDn)
00612 {
00613     nsCOMPtr<nsIAbCard> cardToDelete;
00614     mReplicationDB->GetCardFromAttribute(nsnull, "_DN", NS_ConvertUCS2toUTF8(aDn).get(),
00615                                          PR_FALSE, getter_AddRefs(cardToDelete));
00616     return mReplicationDB->DeleteCard(cardToDelete, PR_FALSE);
00617 }