Landing ChangeLog implementation, bug # 128087

r=dmose, sr=sspitzer, a=asa

Implementation of LDAP queries for changelog and data processing for results
makefile modification and modification for changelog properties
modification of replicationservice to call changelog and related processing.
This commit is contained in:
rdayal%netscape.com 2002-04-09 09:27:26 +00:00
Родитель 368bcb13cf
Коммит 7d3ab432d8
14 изменённых файлов: 1137 добавлений и 249 удалений

Просмотреть файл

@ -135,6 +135,7 @@ endif
ifdef MOZ_LDAP_XPCOM
REQUIRES += mozldap \
uriloader \
windowwatcher \
$(NULL)
EXPORTS += nsAbLDAPDirectoryQuery.h \
@ -145,6 +146,8 @@ EXPORTS += nsAbLDAPDirectoryQuery.h \
nsAbLDAPReplicationService.h \
nsAbLDAPReplicationQuery.h \
nsAbLDAPReplicationData.h \
nsAbLDAPChangeLogQuery.h \
nsAbLDAPChangeLogData.h \
$(NULL)
CPPSRCS += nsAbLDAPDirectory.cpp \
@ -157,6 +160,8 @@ CPPSRCS += nsAbLDAPDirectory.cpp \
nsAbLDAPReplicationService.cpp \
nsAbLDAPReplicationQuery.cpp \
nsAbLDAPReplicationData.cpp \
nsAbLDAPChangeLogQuery.cpp \
nsAbLDAPChangeLogData.cpp \
$(NULL)
endif

Просмотреть файл

@ -1,158 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
MODULE= addrbook
REQUIRES = xpcom \
string \
rdf \
rdfutil \
appshell \
dom \
layout \
widget \
mork \
uriloader \
docshell \
pref \
necko \
locale \
uconv \
unicharutil \
webshell \
msgbase \
msgbaseutil \
mime \
msgcompo \
appcomps \
content \
mozldap \
intl \
layout_xul \
import \
$(NULL)
include <$(DEPTH)\config\config.mak>
################################################################################
## exports
EXPORTS= \
nsAddressBook.h \
nsAddrBookSession.h \
nsAbRDFDataSource.h \
nsDirectoryDataSource.h \
nsAbCardProperty.h \
nsDirPrefs.h \
nsAddrDatabase.h \
nsAbDirProperty.h \
nsAbAutoCompleteSession.h \
nsAbAddressCollecter.h \
nsAddbookProtocolHandler.h \
nsAbMDBDirProperty.h \
nsAbMDBDirectory.h \
nsAbMDBCardProperty.h \
nsAbMDBCard.h \
nsAbBSDirectory.h \
nsAbOutlookDirFactory.h \
nsAbDirFactoryService.h \
nsAddbookUrl.h \
nsAbOutlookDirectory.h \
nsAbOutlookCard.h \
nsAbMDBDirFactory.h \
nsAbDirectoryQuery.h \
nsAbDirectoryQueryProxy.h \
nsAbDirSearchListener.h \
nsAbView.h \
!if !defined(DISABLE_LDAP)
nsAbLDAPDirectoryQuery.h \
nsAbLDAPDirectory.h \
nsAbLDAPDirFactory.h \
nsAbLDAPCard.h \
nsAbLDAPAutoCompFormatter.h \
nsAbLDAPReplicationService.h \
nsAbLDAPReplicationQuery.h \
nsAbLDAPReplicationData.h \
!endif
nsAbDirectoryRDFResource.h \
nsAbBooleanExpression.h \
$(NULL)
################################################################################
## library
LIBRARY_NAME=addrbook_s
CPP_OBJS= \
.\$(OBJDIR)\nsAddressBook.obj \
.\$(OBJDIR)\nsAddrBookSession.obj \
.\$(OBJDIR)\nsAbRDFDataSource.obj \
.\$(OBJDIR)\nsDirectoryDataSource.obj \
.\$(OBJDIR)\nsAbCardProperty.obj \
.\$(OBJDIR)\nsDirPrefs.obj \
.\$(OBJDIR)\nsAddrDatabase.obj \
.\$(OBJDIR)\nsAbDirProperty.obj \
.\$(OBJDIR)\nsAbAutoCompleteSession.obj \
.\$(OBJDIR)\nsAbAddressCollecter.obj \
.\$(OBJDIR)\nsAddbookProtocolHandler.obj \
.\$(OBJDIR)\nsAbMDBDirProperty.obj \
.\$(OBJDIR)\nsAbMDBDirectory.obj \
.\$(OBJDIR)\nsAbMDBCardProperty.obj \
.\$(OBJDIR)\nsAbMDBCard.obj \
.\$(OBJDIR)\nsAbBSDirectory.obj \
.\$(OBJDIR)\nsAddbookUrl.obj \
.\$(OBJDIR)\nsAbDirFactoryService.obj \
.\$(OBJDIR)\nsAbMDBDirFactory.obj \
.\$(OBJDIR)\nsAbOutlookDirectory.obj \
.\$(OBJDIR)\nsAbOutlookCard.obj \
.\$(OBJDIR)\nsAbOutlookDirFactory.obj \
.\$(OBJDIR)\nsMapiAddressBook.obj \
.\$(OBJDIR)\nsAbUtils.obj \
.\$(OBJDIR)\nsAbDirectoryQuery.obj \
.\$(OBJDIR)\nsAbDirectoryQueryProxy.obj \
.\$(OBJDIR)\nsAbDirSearchListener.obj \
.\$(OBJDIR)\nsAbView.obj \
!if !defined(DISABLE_LDAP)
.\$(OBJDIR)\nsAbLDAPDirectory.obj \
.\$(OBJDIR)\nsAbLDAPDirFactory.obj \
.\$(OBJDIR)\nsAbLDAPCard.obj \
.\$(OBJDIR)\nsAbLDAPProperties.obj \
.\$(OBJDIR)\nsAbLDAPDirectoryQuery.obj \
.\$(OBJDIR)\nsAbBoolExprToLDAPFilter.obj \
.\$(OBJDIR)\nsAbLDAPAutoCompFormatter.obj \
.\$(OBJDIR)\nsAbLDAPReplicationService.obj \
.\$(OBJDIR)\nsAbLDAPReplicationQuery.obj \
.\$(OBJDIR)\nsAbLDAPReplicationData.obj \
!endif
.\$(OBJDIR)\nsAbBooleanExpression.obj \
.\$(OBJDIR)\nsAbDirectoryRDFResource.obj \
.\$(OBJDIR)\nsAbQueryStringToExpression.obj \
.\$(OBJDIR)\nsAbWinHelper.obj \
.\$(OBJDIR)\nsWabAddressBook.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

Просмотреть файл

@ -0,0 +1,554 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Rajiv Dayal <rdayal@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsAbLDAPChangeLogData.h"
#include "nsAbLDAPChangeLogQuery.h"
#include "nsLDAP.h"
#include "nsIAbCard.h"
#include "nsIAddrBookSession.h"
#include "nsAbBaseCID.h"
#include "nsAbUtils.h"
#include "nsAbMDBCard.h"
#include "nsAbLDAPCard.h"
#include "nsFileSpec.h"
#include "nsAbLDAPProperties.h"
#include "nsProxiedService.h"
#include "nsAutoLock.h"
#include "nsIAuthPrompt.h"
#include "nsIStringBundle.h"
#include "nsIWindowWatcher.h"
#include "nsUnicharUtils.h"
// defined here since to be used
// only locally to this file.
enum UpdateOp {
NO_OP,
ENTRY_ADD,
ENTRY_DELETE,
ENTRY_MODIFY
};
nsAbLDAPProcessChangeLogData::nsAbLDAPProcessChangeLogData()
: mUseChangeLog(PR_FALSE),
mEntriesAddedQueryCount(0),
mChangeLogEntriesCount(0)
{
mRootDSEEntry.firstChangeNumber = 0;
mRootDSEEntry.lastChangeNumber = 0;
}
nsAbLDAPProcessChangeLogData::~nsAbLDAPProcessChangeLogData()
{
}
NS_IMETHODIMP nsAbLDAPProcessChangeLogData::Init(nsIAbLDAPReplicationQuery * query, nsIWebProgressListener *progressListener)
{
NS_ENSURE_ARG_POINTER(query);
// here we are assuming that the caller will pass a nsAbLDAPChangeLogQuery object,
// an implementation derived from the implementation of nsIAbLDAPReplicationQuery.
nsresult rv = NS_OK;
mChangeLogQuery = do_QueryInterface(query, &rv);
if(NS_FAILED(rv))
return rv;
// call the parent's Init now
return nsAbLDAPProcessReplicationData::Init(query, progressListener);
}
nsresult nsAbLDAPProcessChangeLogData::OnLDAPBind(nsILDAPMessage *aMessage)
{
NS_ENSURE_ARG_POINTER(aMessage);
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
PRInt32 errCode;
nsresult rv = aMessage->GetErrorCode(&errCode);
if(NS_FAILED(rv)) {
Done(PR_FALSE);
return rv;
}
if(errCode != nsILDAPErrors::SUCCESS) {
Done(PR_FALSE);
return NS_ERROR_FAILURE;
}
switch(mState) {
case kAnonymousBinding :
rv = GetAuthData();
if(NS_SUCCEEDED(rv))
rv = mChangeLogQuery->QueryAuthDN(mAuthUserID);
if(NS_SUCCEEDED(rv))
mState = kSearchingAuthDN;
break;
case kAuthenticatedBinding :
rv = mChangeLogQuery->QueryRootDSE();
if(NS_SUCCEEDED(rv))
mState = kSearchingRootDSE;
break;
} //end of switch
if(NS_FAILED(rv))
Abort();
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
{
NS_ENSURE_ARG_POINTER(aMessage);
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
switch(mState)
{
case kSearchingAuthDN :
{
nsXPIDLString authDN;
rv = aMessage->GetDn(getter_Copies(authDN));
if(NS_SUCCEEDED(rv) && !authDN.IsEmpty())
mAuthDN = authDN.get();
}
break;
case kSearchingRootDSE:
rv = ParseRootDSEEntry(aMessage);
break;
case kFindingChanges:
rv = ParseChangeLogEntries(aMessage);
break;
// fall through since we only add (for updates we delete and add)
case kReplicatingChanges:
case kReplicatingAll :
return nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(aMessage);
}
if(NS_FAILED(rv))
Abort();
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::OnLDAPSearchResult(nsILDAPMessage *aMessage)
{
NS_ENSURE_ARG_POINTER(aMessage);
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
PRInt32 errorCode;
nsresult rv = aMessage->GetErrorCode(&errorCode);
if(NS_SUCCEEDED(rv))
{
if(errorCode == nsILDAPErrors::SUCCESS || errorCode == nsILDAPErrors::SIZELIMIT_EXCEEDED) {
switch(mState) {
case kSearchingAuthDN :
rv = OnSearchAuthDNDone();
break;
case kSearchingRootDSE:
{
// before starting the changeLog check the DB file, if its not there or bogus
// we need to create a new one and set to all.
nsCOMPtr<nsIAddrBookSession> abSession = do_GetService(NS_ADDRBOOKSESSION_CONTRACTID, &rv);
if(NS_FAILED(rv))
break;
nsFileSpec* dbPath;
rv = abSession->GetUserProfileDirectory(&dbPath);
if(NS_FAILED(rv))
break;
(*dbPath) += mDirServerInfo->replInfo->fileName;
if (!dbPath->Exists() || !dbPath->GetFileSize())
mUseChangeLog = PR_FALSE;
delete dbPath;
// open / create the AB here since it calls Done,
// just return from here.
if (mUseChangeLog)
rv = OpenABForReplicatedDir(PR_FALSE);
else
rv = OpenABForReplicatedDir(PR_TRUE);
if (NS_FAILED(rv))
return rv;
// now start the appropriate query
rv = OnSearchRootDSEDone();
break;
}
case kFindingChanges:
rv = OnFindingChangesDone();
// if success we return from here since
// this changes state to kReplicatingChanges
// and it falls thru into the if clause below.
if (NS_SUCCEEDED(rv))
return rv;
break;
case kReplicatingAll :
return nsAbLDAPProcessReplicationData::OnLDAPSearchResult(aMessage);
} // end of switch
}
else
rv = NS_ERROR_FAILURE;
// if one of the changed entry in changelog is not found,
// continue with replicating the next one.
if(mState == kReplicatingChanges)
rv = OnReplicatingChangeDone();
} // end of outer if
if(NS_FAILED(rv))
Abort();
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::GetAuthData()
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
if (!wwatch)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAuthPrompt> dialog;
nsresult rv = wwatch->GetNewAuthPrompter(0, getter_AddRefs(dialog));
if (NS_FAILED(rv))
return rv;
if (!dialog)
return NS_ERROR_FAILURE;
nsCOMPtr<nsILDAPURL> url;
rv = mQuery->GetReplicationURL(getter_AddRefs(url));
if (NS_FAILED(rv))
return rv;
nsCAutoString serverUri;
rv = url->GetSpec(serverUri);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
if (NS_FAILED (rv))
return rv ;
nsCOMPtr<nsIStringBundle> bundle;
rv = bundleService->CreateBundle("chrome://messenger/locale/addressbook/addressBook.properties", getter_AddRefs(bundle));
if (NS_FAILED (rv))
return rv ;
nsXPIDLString title;
rv = bundle->GetStringFromName(NS_LITERAL_STRING("AuthDlgTitle").get(), getter_Copies(title));
if (NS_FAILED (rv))
return rv ;
nsXPIDLString desc;
rv = bundle->GetStringFromName(NS_LITERAL_STRING("AuthDlgDesc").get(), getter_Copies(desc));
if (NS_FAILED (rv))
return rv ;
nsXPIDLString username;
nsXPIDLString password;
PRBool btnResult = PR_FALSE;
rv = dialog->PromptUsernameAndPassword(title, desc,
NS_ConvertUTF8toUCS2(serverUri).get(),
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
getter_Copies(username), getter_Copies(password),
&btnResult);
if(NS_SUCCEEDED(rv) && btnResult) {
mAuthUserID = username;
mAuthPswd = password;
mDirServerInfo->enableAuth=PR_TRUE;
mDirServerInfo->savePassword=PR_TRUE;
}
else
rv = NS_ERROR_FAILURE;
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::OnSearchAuthDNDone()
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsILDAPURL> url;
nsresult rv = mQuery->GetReplicationURL(getter_AddRefs(url));
if(NS_SUCCEEDED(rv))
rv = mQuery->ConnectToLDAPServer(url, mAuthDN);
if(NS_SUCCEEDED(rv)) {
mState = kAuthenticatedBinding;
PR_FREEIF(mDirServerInfo->authDn);
mDirServerInfo->authDn=ToNewCString(NS_ConvertUCS2toUTF8(mAuthDN));
}
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::ParseRootDSEEntry(nsILDAPMessage *aMessage)
{
NS_ENSURE_ARG_POINTER(aMessage);
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
// populate the RootDSEChangeLogEntry
CharPtrArrayGuard attrs;
nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr());
// no attributes !!!
if(NS_FAILED(rv))
return rv;
for(PRInt32 i=attrs.GetSize()-1; i >= 0; i--) {
PRUnicharPtrArrayGuard vals;
rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr());
if(NS_FAILED(rv))
continue;
if(vals.GetSize()) {
if (!PL_strcasecmp(attrs[i], "changelog"))
mRootDSEEntry.changeLogDN = vals[0];
if (!PL_strcasecmp(attrs[i], "firstChangeNumber"))
mRootDSEEntry.firstChangeNumber = atol(NS_LossyConvertUCS2toASCII(vals[0]).get());
if (!PL_strcasecmp(attrs[i], "lastChangeNumber"))
mRootDSEEntry.lastChangeNumber = atol(NS_LossyConvertUCS2toASCII(vals[0]).get());
if (!PL_strcasecmp(attrs[i], "dataVersion"))
mRootDSEEntry.dataVersion = NS_ConvertUCS2toUTF8(vals[0]).get();
}
}
if((mRootDSEEntry.lastChangeNumber > 0)
&& (mDirServerInfo->replInfo->lastChangeNumber < mRootDSEEntry.lastChangeNumber)
&& (mDirServerInfo->replInfo->lastChangeNumber > mRootDSEEntry.firstChangeNumber)
)
mUseChangeLog = PR_TRUE;
if(mRootDSEEntry.lastChangeNumber && (mDirServerInfo->replInfo->lastChangeNumber == mRootDSEEntry.lastChangeNumber)) {
Done(PR_TRUE); // we are up to date no need to replicate, db not open yet so call Done
return NS_OK;
}
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::OnSearchRootDSEDone()
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
if(mUseChangeLog) {
rv = mChangeLogQuery->QueryChangeLog(mRootDSEEntry.changeLogDN, mRootDSEEntry.lastChangeNumber);
if (NS_FAILED(rv))
return rv;
mState = kFindingChanges;
if(mListener)
mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_FALSE);
}
else {
rv = mQuery->QueryAllEntries();
if (NS_FAILED(rv))
return rv;
mState = kReplicatingAll;
if(mListener)
mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_TRUE);
}
mDirServerInfo->replInfo->lastChangeNumber = mRootDSEEntry.lastChangeNumber;
PR_FREEIF(mDirServerInfo->replInfo->dataVersion);
mDirServerInfo->replInfo->dataVersion = ToNewCString(mRootDSEEntry.dataVersion);
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::ParseChangeLogEntries(nsILDAPMessage *aMessage)
{
NS_ENSURE_ARG_POINTER(aMessage);
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
// populate the RootDSEChangeLogEntry
CharPtrArrayGuard attrs;
nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr());
// no attributes
if(NS_FAILED(rv))
return rv;
nsAutoString targetDN;
UpdateOp operation = NO_OP;
for(PRInt32 i = attrs.GetSize()-1; i >= 0; i--) {
PRUnicharPtrArrayGuard vals;
rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr());
if(NS_FAILED(rv))
continue;
if(vals.GetSize()) {
if (!PL_strcasecmp(attrs[i], "targetdn"))
targetDN = vals[0];
if (!PL_strcasecmp(attrs[i], "changetype")) {
if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("add"), nsCaseInsensitiveStringComparator()))
operation = ENTRY_ADD;
if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("modify"), nsCaseInsensitiveStringComparator()))
operation = ENTRY_MODIFY;
if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("delete"), nsCaseInsensitiveStringComparator()))
operation = ENTRY_DELETE;
}
}
}
mChangeLogEntriesCount++;
if(!(mChangeLogEntriesCount % 10)) { // inform the listener every 10 entries
mListener->OnProgressChange(nsnull,nsnull,mChangeLogEntriesCount, -1, mChangeLogEntriesCount, -1);
// in case if the LDAP Connection thread is starved and causes problem
// uncomment this one and try.
// PR_Sleep(PR_INTERVAL_NO_WAIT); // give others a chance
}
#ifdef DEBUG_rdayal
printf ("ChangeLog Replication : Updated Entry : %s for OpType : %u\n",
NS_ConvertUCS2toUTF8(targetDN).get(), operation);
#endif
switch(operation) {
case ENTRY_ADD:
// add the DN to the add list if not already in the list
if(!(mEntriesToAdd.IndexOf(targetDN) >= 0))
mEntriesToAdd.AppendString(targetDN);
break;
case ENTRY_DELETE:
// donot check the return here since delete may fail if
// entry deleted in changelog doesnot exist in DB
// for e.g if the user specifies a filter, so go next entry
DeleteCard(targetDN);
break;
case ENTRY_MODIFY:
// for modify, delte the entry from DB and add updated entry
// we do this since we cannot access the changes attribs of changelog
rv = DeleteCard(targetDN);
if (NS_SUCCEEDED(rv))
if(!(mEntriesToAdd.IndexOf(targetDN) >= 0))
mEntriesToAdd.AppendString(targetDN);
break;
default:
// should not come here, would come here only
// if the entry is not a changeLog entry
NS_WARNING("nsAbLDAPProcessChangeLogData::ParseChangeLogEntries"
"Not an changelog entry");
}
// go ahead processing the next entry, a modify or delete DB operation
// can 'correctly' fail if the entry is not present in the DB.
// eg : in case a filter is specified.
return NS_OK;
}
nsresult nsAbLDAPProcessChangeLogData::OnFindingChangesDone()
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
#ifdef DEBUG_rdayal
printf ("ChangeLog Replication : Finding Changes Done \n");
#endif
nsresult rv = NS_OK;
// no entries to add/update (for updates too we delete and add) entries,
// we took care of deletes in ParseChangeLogEntries, all Done!
mEntriesAddedQueryCount = mEntriesToAdd.Count();
if(mEntriesAddedQueryCount <= 0) {
if(mReplicationDB && mDBOpen) {
// close the DB, no need to commit since we have not made
// any changes yet to the DB.
rv = mReplicationDB->Close(PR_FALSE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB Close(no commit) on Success failed");
mDBOpen = PR_FALSE;
// once are done with the replication file, delete the backup file
if(mBackupReplicationFile) {
rv = mBackupReplicationFile->Remove(PR_FALSE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Replication BackupFile Remove on Success failed");
}
}
Done(PR_TRUE);
return NS_OK;
}
// decrement the count first to get the correct array element
mEntriesAddedQueryCount--;
rv = mChangeLogQuery->QueryChangedEntries(*(mEntriesToAdd[mEntriesAddedQueryCount]));
if (NS_FAILED(rv))
return rv;
if(mListener && NS_SUCCEEDED(rv))
mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_TRUE);
mState = kReplicatingChanges;
return rv;
}
nsresult nsAbLDAPProcessChangeLogData::OnReplicatingChangeDone()
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
if(!mEntriesAddedQueryCount)
{
if(mReplicationDB && mDBOpen) {
rv = mReplicationDB->Close(PR_TRUE); // commit and close the DB
NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB Close (commit) on Success failed");
mDBOpen = PR_FALSE;
}
// once we done with the replication file, delete the backup file
if(mBackupReplicationFile) {
rv = mBackupReplicationFile->Remove(PR_FALSE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Replication BackupFile Remove on Success failed");
}
Done(PR_TRUE); // all data is recieved
return NS_OK;
}
// remove the entry already added from the list and query the next one
if(mEntriesAddedQueryCount < mEntriesToAdd.Count() && mEntriesAddedQueryCount >= 0)
mEntriesToAdd.RemoveStringAt(mEntriesAddedQueryCount);
mEntriesAddedQueryCount--;
rv = mChangeLogQuery->QueryChangedEntries(*(mEntriesToAdd[mEntriesAddedQueryCount]));
return rv;
}

Просмотреть файл

@ -0,0 +1,90 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Rajiv Dayal <rdayal@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsAbLDAPChangeLogData_h__
#define nsAbLDAPChangeLogData_h__
#include "nsAbLDAPReplicationData.h"
#include "nsAbLDAPChangeLogQuery.h"
#include "nsVoidArray.h"
typedef struct {
nsString changeLogDN;
PRInt32 firstChangeNumber;
PRInt32 lastChangeNumber;
nsCString dataVersion;
} RootDSEChangeLogEntry;
class nsAbLDAPProcessChangeLogData : public nsAbLDAPProcessReplicationData
{
public :
nsAbLDAPProcessChangeLogData();
~nsAbLDAPProcessChangeLogData();
NS_IMETHOD Init(nsIAbLDAPReplicationQuery * query, nsIWebProgressListener *progressListener);
protected :
nsCOMPtr <nsIAbLDAPChangeLogQuery> mChangeLogQuery;
nsresult OnLDAPBind(nsILDAPMessage *aMessage);
nsresult OnLDAPSearchEntry(nsILDAPMessage *aMessage);
nsresult OnLDAPSearchResult(nsILDAPMessage *aMessage);
nsresult ParseChangeLogEntries(nsILDAPMessage *aMessage);
nsresult ParseRootDSEEntry(nsILDAPMessage *aMessage);
nsresult GetAuthData(); // displays username and password prompt
nsString mAuthUserID; // user id of the user making the connection
nsresult OnSearchAuthDNDone();
nsresult OnSearchRootDSEDone();
nsresult OnFindingChangesDone();
nsresult OnReplicatingChangeDone();
RootDSEChangeLogEntry mRootDSEEntry;
PRBool mUseChangeLog;
PRInt32 mChangeLogEntriesCount;
PRInt32 mEntriesAddedQueryCount;
nsStringArray mEntriesToAdd;
};
#endif // nsAbLDAPChangeLogData_h__

Просмотреть файл

@ -0,0 +1,191 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Rajiv Dayal <rdayal@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsAbLDAPChangeLogQuery.h"
#include "nsAbLDAPReplicationService.h"
#include "nsAbLDAPChangeLogData.h"
#include "nsAbLDAPProperties.h"
#include "nsAutoLock.h"
#include "nsAbUtils.h"
#include "prprf.h"
#include "nsDirPrefs.h"
#include "nsAbBaseCID.h"
#include "nsPrintfCString.h"
NS_IMPL_ISUPPORTS_INHERITED1(nsAbLDAPChangeLogQuery, nsAbLDAPReplicationQuery, nsIAbLDAPChangeLogQuery)
nsAbLDAPChangeLogQuery::nsAbLDAPChangeLogQuery()
{
NS_INIT_ISUPPORTS();
}
nsAbLDAPChangeLogQuery::~nsAbLDAPChangeLogQuery()
{
}
// this is to be defined only till this is not hooked to SSL to get authDN and authPswd
#define USE_AUTHDLG
NS_IMETHODIMP nsAbLDAPChangeLogQuery::Init(const nsACString & aPrefName, nsIWebProgressListener *aProgressListener)
{
if(aPrefName.IsEmpty())
return NS_ERROR_UNEXPECTED;
mDirPrefName = aPrefName;
nsresult rv = InitLDAPData();
if(NS_FAILED(rv))
return rv;
// create the ChangeLog Data Processor
mDataProcessor = do_CreateInstance(NS_ABLDAP_PROCESSCHANGELOGDATA_CONTRACTID, &rv);
if(NS_FAILED(rv))
return rv;
// 'this' initialized
mInitialized = PR_TRUE;
return mDataProcessor->Init(this, aProgressListener);
}
NS_IMETHODIMP nsAbLDAPChangeLogQuery::DoReplicationQuery()
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
#ifdef USE_AUTHDLG
return ConnectToLDAPServer(mURL, NS_LITERAL_STRING(""));
#else
mDataProcessor->PopulateAuthData();
return ConnectToLDAPServer(mURL, mAuthDN);
#endif
}
NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryAuthDN(const nsAString & aValueUsedToFindDn)
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
CharPtrArrayGuard attributes;
*attributes.GetSizeAddr() = 2;
*attributes.GetArrayAddr() = NS_STATIC_CAST(char **, nsMemory::Alloc((*attributes.GetSizeAddr()) * sizeof(char *)));
attributes.GetArray()[0] = ToNewCString(nsDependentCString(DIR_GetFirstAttributeString(mDirServer, cn)));
attributes.GetArray()[1] = nsnull;
nsAutoString filter;
filter.AssignWithConversion(DIR_GetFirstAttributeString(mDirServer, auth));
filter.AppendWithConversion(NS_LITERAL_CSTRING("=").get());
filter += aValueUsedToFindDn;
nsXPIDLCString dn;
rv = mURL->GetDn(getter_Copies(dn));
if(NS_FAILED(rv))
return rv;
return mOperation->SearchExt(NS_ConvertUTF8toUCS2(dn).get(), nsILDAPURL::SCOPE_SUBTREE,
filter.get(),
attributes.GetSize(), attributes.GetArray(),
0, 0);
}
NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryRootDSE()
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
return mOperation->SearchExt(nsnull, nsILDAPURL::SCOPE_BASE,
NS_LITERAL_STRING("objectclass=*").get(),
MozillaLdapPropertyRelator::rootDSEAttribCount,
MozillaLdapPropertyRelator::changeLogRootDSEAttribs,
0, 0);
}
NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryChangeLog(const nsAString & aChangeLogDN, PRInt32 aLastChangeNo)
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
if(aChangeLogDN.IsEmpty())
return NS_ERROR_UNEXPECTED;
// make sure that the filter here just have one condition
// and should not be enclosed in enclosing brackets.
// also condition '>' doesnot work, it should be '>='/
nsCAutoString filter (NS_LITERAL_CSTRING("changenumber>="));
filter.AppendInt(mDirServer->replInfo->lastChangeNumber+1);
return mOperation->SearchExt(PromiseFlatString(aChangeLogDN).get(),
nsILDAPURL::SCOPE_ONELEVEL,
NS_ConvertUTF8toUCS2(filter).get(),
MozillaLdapPropertyRelator::changeLogEntryAttribCount,
MozillaLdapPropertyRelator::changeLogEntryAttribs,
0, 0);
}
NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryChangedEntries(const nsAString & aChangedEntryDN)
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
if(aChangedEntryDN.IsEmpty())
return NS_ERROR_UNEXPECTED;
nsXPIDLCString urlFilter;
nsresult rv = mURL->GetFilter(getter_Copies(urlFilter));
if(NS_FAILED(rv))
return rv;
PRInt32 scope;
rv = mURL->GetScope(&scope);
if(NS_FAILED(rv))
return rv;
CharPtrArrayGuard attributes;
rv = mURL->GetAttributes(attributes.GetSizeAddr(), attributes.GetArrayAddr());
if(NS_FAILED(rv))
return rv;
return mOperation->SearchExt(PromiseFlatString(aChangedEntryDN).get(), scope,
NS_ConvertUTF8toUCS2(urlFilter).get(),
attributes.GetSize(), attributes.GetArray(),
0, 0);
}

Просмотреть файл

@ -0,0 +1,59 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Rajiv Dayal <rdayal@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsAbLDAPChangeLogQuery_h__
#define nsAbLDAPChangeLogQuery_h__
#include "nsAbLDAPReplicationQuery.h"
#include "nsString.h"
class nsAbLDAPChangeLogQuery : public nsIAbLDAPChangeLogQuery,
public nsAbLDAPReplicationQuery
{
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIABLDAPCHANGELOGQUERY
nsAbLDAPChangeLogQuery();
virtual ~nsAbLDAPChangeLogQuery();
NS_IMETHOD DoReplicationQuery();
NS_IMETHOD Init(const nsACString & aPrefName, nsIWebProgressListener *aProgressListener);
};
#endif // nsAbLDAPChangeLogQuery_h__

Просмотреть файл

@ -44,6 +44,7 @@
#include "nsString.h"
#include "nsReadableUtils.h"
/*
Table defining the relationship between
mozilla card properties and corresponding
@ -180,6 +181,24 @@ static MozillaLdapPropertyRelation mozillaLdapPropertyTable[] =
const MozillaLdapPropertyRelation* MozillaLdapPropertyRelator::table = mozillaLdapPropertyTable;
const int MozillaLdapPropertyRelator::tableSize = sizeof (mozillaLdapPropertyTable) / sizeof (MozillaLdapPropertyRelation);
static const char * sLDAPChangeLogRootDSEAttribs[] =
{
"changelog",
"firstChangeNumber",
"lastChangeNumber",
"dataVersion"
};
static const char * sLDAPChangeLogEntryAttribs[] =
{
"targetdn",
"changetype"
};
const char ** MozillaLdapPropertyRelator::changeLogRootDSEAttribs = sLDAPChangeLogRootDSEAttribs;
const int MozillaLdapPropertyRelator::rootDSEAttribCount = sizeof(sLDAPChangeLogRootDSEAttribs)/sizeof(char**);
const char ** MozillaLdapPropertyRelator::changeLogEntryAttribs = sLDAPChangeLogEntryAttribs;
const int MozillaLdapPropertyRelator::changeLogEntryAttribCount = sizeof(sLDAPChangeLogEntryAttribs)/sizeof(char**);
PRBool MozillaLdapPropertyRelator::IsInitialized = PR_FALSE ;
nsHashtable MozillaLdapPropertyRelator::mMozillaToLdap;
nsHashtable MozillaLdapPropertyRelator::mLdapToMozilla;
@ -198,6 +217,7 @@ void MozillaLdapPropertyRelator::Initialize(void)
IsInitialized = PR_TRUE;
}
nsresult MozillaLdapPropertyRelator::GetAllSupportedLDAPAttributes(nsCString &aResult)
{
if (tableSize < 1)
@ -268,4 +288,3 @@ nsresult MozillaLdapPropertyRelator::createCardPropertyFromLDAPMessage (nsILDAPM
return rv;
}

Просмотреть файл

@ -71,6 +71,12 @@ public:
static nsHashtable mMozillaToLdap ;
static PRBool IsInitialized;
static const char ** changeLogRootDSEAttribs;
static const char ** changeLogEntryAttribs;
static const int rootDSEAttribCount;
static const int changeLogEntryAttribCount;
public:
static const MozillaLdapPropertyRelation* findMozillaPropertyFromLdap (const char* ldapProperty);
static const MozillaLdapPropertyRelation* findLdapPropertyFromMozilla (const char* mozillaProperty);

Просмотреть файл

@ -48,19 +48,24 @@
#include "nsAbLDAPProperties.h"
#include "nsAbLDAPReplicationQuery.h"
#include "nsProxiedService.h"
#include "nsCPasswordManager.h"
#include "nsIRDFService.h"
#include "nsIRDFResource.h"
// once bug # 101252 gets fixed, this should be reverted back to be non threadsafe
// implementation is not really thread safe since each object should exist
// independently along with its related independent nsAbLDAPReplicationQuery object.
NS_IMPL_THREADSAFE_ISUPPORTS2(nsAbLDAPProcessReplicationData, nsIAbLDAPProcessReplicationData, nsILDAPMessageListener)
nsAbLDAPProcessReplicationData::nsAbLDAPProcessReplicationData()
: mState(kQueryNotStarted),
: mState(kIdle),
mProtocol(-1),
mCount(0),
mReplInfo(nsnull),
mDirServerInfo(nsnull),
mInitialized(PR_FALSE),
mDBOpen(PR_FALSE)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
nsAbLDAPProcessReplicationData::~nsAbLDAPProcessReplicationData()
@ -74,16 +79,14 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Init(nsIAbLDAPReplicationQuery *qu
{
NS_ENSURE_ARG_POINTER(query);
nsresult rv = NS_OK;
mQuery = query;
rv = mQuery->GetReplicationInfo(&mReplInfo);
nsresult rv = mQuery->GetReplicationServerInfo(&mDirServerInfo);
if(NS_FAILED(rv)) {
mQuery = nsnull;
return rv;
}
if(!mReplInfo) {
if(!mDirServerInfo) {
mQuery = nsnull;
return NS_ERROR_FAILURE;
}
@ -106,7 +109,6 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::GetReplicationState(PRInt32 *aRepl
NS_IMETHODIMP nsAbLDAPProcessReplicationData::GetProtocolUsed(PRInt32 *aProtocolUsed)
{
NS_ENSURE_ARG_POINTER(aProtocolUsed);
*aProtocolUsed = mProtocol;
return NS_OK;
}
@ -116,16 +118,14 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPInit(nsresult aStatus)
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
// Make sure that the Init() worked properly
if(NS_FAILED(aStatus)) {
Done(PR_FALSE);
return rv;
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsILDAPMessageListener> listener;
rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ,
nsresult rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ,
NS_GET_IID(nsILDAPMessageListener),
NS_STATIC_CAST(nsILDAPMessageListener*, this),
PROXY_SYNC | PROXY_ALWAYS,
@ -156,10 +156,17 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPInit(nsresult aStatus)
}
// Bind
if(mAuthPswd.IsEmpty()) {
rv = operation->SimpleBind(nsnull);
mState = kAnonymousBinding;
}
else {
rv = operation->SimpleBind(mAuthPswd.get());
mState = kAuthenticatedBinding;
}
if(NS_FAILED(rv)) {
Done(PR_FALSE);
return rv;
}
return rv;
@ -171,10 +178,8 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPMessage(nsILDAPMessage *aMes
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
PRInt32 messageType;
rv = aMessage->GetType(&messageType);
nsresult rv = aMessage->GetType(&messageType);
if(NS_FAILED(rv)) {
#ifdef DEBUG_rdayal
printf("LDAP Replication : OnLDAPMessage : couldnot GetType \n");
@ -208,15 +213,17 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Abort()
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
#ifdef DEBUG_rdayal
printf ("ChangeLog Replication : ABORT called !!! \n");
#endif
nsCOMPtr<nsILDAPOperation> operation;
rv = mQuery->GetOperation(getter_AddRefs(operation));
if(operation && mState != kQueryNotStarted)
nsresult rv = mQuery->GetOperation(getter_AddRefs(operation));
if(operation && mState != kIdle)
{
rv = operation->Abandon();
if(NS_SUCCEEDED(rv))
mState = kQueryNotStarted;
mState = kIdle;
}
if(mReplicationDB && mDBOpen) {
@ -228,8 +235,8 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Abort()
rv = mReplicationFile->Remove(PR_FALSE);
if(NS_SUCCEEDED(rv)) {
// now put back the backed up replicated file if aborted
if(mBackupReplicationFile)
rv = mBackupReplicationFile->MoveTo(nsnull, mReplInfo->fileName);
if(mBackupReplicationFile && mDirServerInfo->replInfo)
rv = mBackupReplicationFile->MoveTo(nsnull, mDirServerInfo->replInfo->fileName);
}
}
}
@ -240,6 +247,41 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Abort()
return rv;
}
// this should get the authDN from prefs and password from PswdMgr
NS_IMETHODIMP nsAbLDAPProcessReplicationData::PopulateAuthData()
{
mAuthDN.AssignWithConversion(mDirServerInfo->authDn);
nsresult rv = NS_OK;
nsCOMPtr <nsIPasswordManagerInternal> passwordMgrInt = do_GetService(NS_PASSWORDMANAGER_CONTRACTID, &rv);
if(NS_SUCCEEDED(rv) && passwordMgrInt) {
// Get the current server URI
nsCOMPtr<nsILDAPURL> url;
rv = mQuery->GetReplicationURL(getter_AddRefs(url));
if (NS_FAILED(rv))
return rv;
nsCAutoString serverUri;
rv = url->GetSpec(serverUri);
if (NS_FAILED(rv))
return rv;
nsCAutoString hostFound;
nsAutoString userNameFound;
nsAutoString passwordFound;
// Get password entry corresponding to the server URI we are passing in.
rv = passwordMgrInt->FindPasswordEntry(serverUri, NS_LITERAL_STRING(""), NS_LITERAL_STRING(""),
hostFound, userNameFound, passwordFound);
if (NS_FAILED(rv))
return rv;
if (!passwordFound.IsEmpty())
mAuthPswd = passwordFound;
}
return rv;
}
nsresult nsAbLDAPProcessReplicationData::OnLDAPBind(nsILDAPMessage *aMessage)
{
NS_ENSURE_ARG_POINTER(aMessage);
@ -259,9 +301,9 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPBind(nsILDAPMessage *aMessage)
return NS_ERROR_FAILURE;
}
rv = CreateABForReplicatedDir();
rv = OpenABForReplicatedDir(PR_TRUE);
if(NS_FAILED(rv)) {
// do not call Done here since CreateABForReplicationDir calls it.
// do not call done here since it is called by OpenABForReplicationDir
return rv;
}
@ -289,14 +331,10 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess
if(!mReplicationDB || !mDBOpen)
return NS_ERROR_FAILURE;
nsresult rv;
nsAbLDAPCard card;
PRBool hasSetCardProperty = PR_FALSE;
rv = MozillaLdapPropertyRelator::createCardPropertyFromLDAPMessage(aMessage,
nsresult rv = MozillaLdapPropertyRelator::createCardPropertyFromLDAPMessage(aMessage,
&card, &hasSetCardProperty);
if(NS_FAILED(rv)) {
Abort();
@ -305,11 +343,12 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess
if(hasSetCardProperty == PR_FALSE)
{
Abort();
return NS_ERROR_FAILURE;
NS_WARNING("nsAbLDAPProcessReplicationData::OnLDAPSearchEntry"
"No card Properties found and set");
// if some entries are bogus for us, continue with next one
return NS_OK;
}
#ifdef DEBUG_rdayal
nsXPIDLString firstName;
rv = card.GetFirstName(getter_Copies(firstName));
@ -324,7 +363,6 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess
printf("\n LDAPReplication :: got card #: %d, name: %s \n", mCount, name.get());
#endif
nsCOMPtr<nsIAbMDBCard> dbCard;
dbCard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv);
if(NS_FAILED(rv)) {
@ -351,6 +389,28 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess
return rv;
}
// now set the attribute for the DN of the entry in the card in the DB
nsXPIDLString authDN;
rv = aMessage->GetDn(getter_Copies(authDN));
if(NS_SUCCEEDED(rv) && !authDN.IsEmpty())
{
dbCard->SetAbDatabase(mReplicationDB);
dbCard->SetStringAttribute("_DN", authDN.get());
}
newCard = do_QueryInterface(dbCard, &rv);
if(NS_FAILED(rv)) {
Abort();
return rv;
}
rv = mReplicationDB->EditCard(newCard, PR_FALSE);
if(NS_FAILED(rv)) {
Abort();
return rv;
}
mCount ++;
if(!(mCount % 10)) // inform the listener every 10 entries
@ -375,9 +435,8 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchResult(nsILDAPMessage *aMes
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
PRInt32 errorCode;
rv = aMessage->GetErrorCode(&errorCode);
nsresult rv = aMessage->GetErrorCode(&errorCode);
if(NS_SUCCEEDED(rv)) {
// We are done with the LDAP search for all entries.
@ -411,9 +470,9 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchResult(nsILDAPMessage *aMes
NS_ASSERTION(NS_SUCCEEDED(rv), "Replication File Remove on Failure failed");
if(NS_SUCCEEDED(rv)) {
// now put back the backed up replicated file
if(mBackupReplicationFile)
if(mBackupReplicationFile && mDirServerInfo->replInfo)
{
rv = mBackupReplicationFile->MoveTo(nsnull, mReplInfo->fileName);
rv = mBackupReplicationFile->MoveTo(nsnull, mDirServerInfo->replInfo->fileName);
NS_ASSERTION(NS_SUCCEEDED(rv), "Replication Backup File Move back on Failure failed");
}
}
@ -424,7 +483,7 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchResult(nsILDAPMessage *aMes
return NS_OK;
}
nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir()
nsresult nsAbLDAPProcessReplicationData::OpenABForReplicatedDir(PRBool aCreate)
{
if(!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
@ -437,7 +496,7 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir()
return rv;
}
if(!mReplInfo->fileName) {
if(!mDirServerInfo->replInfo->fileName) {
Done(PR_FALSE);
return NS_ERROR_FAILURE;
}
@ -449,7 +508,7 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir()
return rv;
}
(*dbPath) += mReplInfo->fileName;
(*dbPath) += mDirServerInfo->replInfo->fileName;
// if the AB DB already exists backup existing one,
// in case if the user cancels or Abort put back the backed up file
@ -461,10 +520,12 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir()
Done(PR_FALSE);
return rv;
}
// create the backup file object same as replication file object
// create the backup file object same as the Replication file object.
// we create a backup file here since we need to cleanup the existing file
// and then commit so instead of deleting existing cards we just clone the
// existing one for a much better performance.
// for create and then commit so instead of deleting existing cards we just
// clone the existing one for a much better performance - for Download All.
// And also important in case if replication fails we donot lose user's existing
// replicated data for both Download all and Changelog.
rv = mReplicationFile->Clone(getter_AddRefs(mBackupReplicationFile));
if(NS_FAILED(rv)) {
delete dbPath;
@ -477,16 +538,43 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir()
Done(PR_FALSE);
return rv;
}
nsXPIDLCString backupFilePath;
rv = mBackupReplicationFile->GetLeafName(getter_Copies(backupFilePath));
nsXPIDLCString backupFileLeafName;
rv = mBackupReplicationFile->GetLeafName(getter_Copies(backupFileLeafName));
if(NS_FAILED(rv)) {
delete dbPath;
Done(PR_FALSE);
return rv;
}
// remove the newly created unique backup file so that move and copy succeeds.
rv = mBackupReplicationFile->Remove(PR_FALSE);
if(NS_FAILED(rv)) {
delete dbPath;
Done(PR_FALSE);
return rv;
}
rv = mBackupReplicationFile->MoveTo(nsnull, backupFilePath.get());
// this will take care of all failed cases for moving to backup file above
if(aCreate) {
// set backup file to existing replication file for move
mBackupReplicationFile->SetLeafName(mDirServerInfo->replInfo->fileName);
rv = mBackupReplicationFile->MoveTo(nsnull, backupFileLeafName.get());
// set the backup file leaf name now
if (NS_SUCCEEDED(rv))
mBackupReplicationFile->SetLeafName(backupFileLeafName.get());
}
else {
// set backup file to existing replication file for copy
mBackupReplicationFile->SetLeafName(mDirServerInfo->replInfo->fileName);
// specify the parent here specifically,
// passing nsnull to copy to the same dir actually renames existing file
// instead of making another copy of the existing file.
nsCOMPtr<nsIFile> parent;
rv = mBackupReplicationFile->GetParent(getter_AddRefs(parent));
if (NS_SUCCEEDED(rv))
rv = mBackupReplicationFile->CopyTo(parent, backupFileLeafName.get());
// set the backup file leaf name now
if (NS_SUCCEEDED(rv))
mBackupReplicationFile->SetLeafName(backupFileLeafName.get());
}
if(NS_FAILED(rv)) {
delete dbPath;
Done(PR_FALSE);
@ -498,14 +586,18 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir()
do_GetService(NS_ADDRDATABASE_CONTRACTID, &rv);
if(NS_FAILED(rv)) {
delete dbPath;
if (mBackupReplicationFile)
mBackupReplicationFile->Remove(PR_FALSE);
Done(PR_FALSE);
return rv;
}
rv = addrDBFactory->Open(dbPath, PR_TRUE, getter_AddRefs(mReplicationDB), PR_TRUE);
rv = addrDBFactory->Open(dbPath, aCreate, getter_AddRefs(mReplicationDB), PR_TRUE);
delete dbPath;
if(NS_FAILED(rv)) {
Done(PR_FALSE);
if (mBackupReplicationFile)
mBackupReplicationFile->Remove(PR_FALSE);
return rv;
}
@ -518,6 +610,8 @@ void nsAbLDAPProcessReplicationData::Done(PRBool aSuccess)
if(!mInitialized)
return;
mState = kReplicationDone;
mQuery->Done(aSuccess);
if(mListener)
@ -527,3 +621,11 @@ void nsAbLDAPProcessReplicationData::Done(PRBool aSuccess)
// releas the query now.
mQuery = nsnull;
}
nsresult nsAbLDAPProcessReplicationData::DeleteCard(nsString & aDn)
{
nsCOMPtr<nsIAbCard> cardToDelete;
mReplicationDB->GetCardFromAttribute(nsnull, "_DN", NS_ConvertUCS2toUTF8(aDn).get(),
PR_FALSE, getter_AddRefs(cardToDelete));
return mReplicationDB->DeleteCard(cardToDelete, PR_FALSE);
}

Просмотреть файл

@ -72,13 +72,16 @@ protected :
PRBool mDBOpen;
PRBool mInitialized;
DIR_ReplicationInfo * mReplInfo;
DIR_Server * mDirServerInfo;
nsString mAuthDN; // authDN of the user
nsString mAuthPswd; // pswd of the authDN user
virtual nsresult OnLDAPBind(nsILDAPMessage *aMessage);
virtual nsresult OnLDAPSearchEntry(nsILDAPMessage *aMessage);
virtual nsresult OnLDAPSearchResult(nsILDAPMessage *aMessage);
nsresult CreateABForReplicatedDir();
nsresult OpenABForReplicatedDir(PRBool bCreate);
nsresult DeleteCard(nsString & aDn);
void Done(PRBool aSuccess);
};

Просмотреть файл

@ -56,7 +56,6 @@ nsAbLDAPReplicationQuery::nsAbLDAPReplicationQuery()
mInitialized(PR_FALSE)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
nsAbLDAPReplicationQuery::~nsAbLDAPReplicationQuery()
@ -77,9 +76,15 @@ nsresult nsAbLDAPReplicationQuery::InitLDAPData()
// this is done here to take care of the problem related to bug # 99124.
// earlier versions of Mozilla could have the fileName associated with the directory
// to be abook.mab which is the profile's personal addressbook. If the pref points to
// it generate a new filename and set it as the replication filename.
if (!nsCRT::strcasecmp(mDirServer->fileName,kPersonalAddressbook) || !mDirServer->fileName)
DIR_SetServerFileName(mDirServer, mDirServer->serverName);
// it, calls nsDirPrefs to generate a new server filename.
if (!nsCRT::strcasecmp(mDirServer->fileName,kPersonalAddressbook)
|| !mDirServer->fileName || !(*mDirServer->fileName)) {
// initialize mDirServer->filename is null or else DIR_SetServerFileName doesnot work
// and no point in passing the 2nd param (leafName) to it as it doesnot use that.
PR_FREEIF(mDirServer->fileName);
mDirServer->fileName=nsnull;
DIR_SetServerFileName (mDirServer, nsnull);
}
// use the dir server filename for replication
PR_FREEIF(mDirServer->replInfo->fileName);
// since DeleteServer frees the replInfo->fileName make a copy of string
@ -105,15 +110,14 @@ nsresult nsAbLDAPReplicationQuery::InitLDAPData()
return rv;
}
nsresult nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL * aURL)
NS_IMETHODIMP nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL *aURL, const nsAString & aAuthDN)
{
NS_ENSURE_ARG_POINTER(aURL);
if (!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
nsCAutoString host;
rv = aURL->GetHost(host);
nsresult rv = aURL->GetHost(host);
if (NS_FAILED(rv))
return rv;
if (host.IsEmpty())
@ -126,13 +130,6 @@ nsresult nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL * aURL)
if (!port)
return NS_ERROR_UNEXPECTED;
nsXPIDLCString dn;
rv = aURL->GetDn(getter_Copies(dn));
if (NS_FAILED(rv))
return rv;
if (dn.IsEmpty())
return NS_ERROR_UNEXPECTED;
// Initiate LDAP message listener to the current thread
nsCOMPtr<nsILDAPMessageListener> listener;
rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ,
@ -143,8 +140,26 @@ nsresult nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL * aURL)
if (!listener)
return NS_ERROR_FAILURE;
// this could be a rebind call
PRInt32 replicationState = nsIAbLDAPProcessReplicationData::kIdle;
rv = mDataProcessor->GetReplicationState(&replicationState);
if(NS_FAILED(rv))
return rv;
if((replicationState != nsIAbLDAPProcessReplicationData::kIdle))
{
// release old and create a new instance
mConnection = do_CreateInstance(NS_LDAPCONNECTION_CONTRACTID, &rv);
if(NS_FAILED(rv))
return rv;
// release old and create a new instance
mOperation = do_CreateInstance(NS_LDAPOPERATION_CONTRACTID, &rv);
if(NS_FAILED(rv))
return rv;
}
// initialize the LDAP connection
return mConnection->Init(host.get(), port, NS_ConvertUTF8toUCS2(dn).get(), listener);
return mConnection->Init(host.get(), port, PromiseFlatString(aAuthDN).get(), listener);
}
NS_IMETHODIMP nsAbLDAPReplicationQuery::Init(const nsACString & aPrefName, nsIWebProgressListener *aProgressListener)
@ -154,9 +169,7 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::Init(const nsACString & aPrefName, nsIWe
mDirPrefName = aPrefName;
nsresult rv = NS_OK;
rv = InitLDAPData();
nsresult rv = InitLDAPData();
if (NS_FAILED(rv))
return rv;
@ -172,7 +185,7 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::Init(const nsACString & aPrefName, nsIWe
NS_IMETHODIMP nsAbLDAPReplicationQuery::DoReplicationQuery()
{
return ConnectToLDAPServer(mURL);
return ConnectToLDAPServer(mURL, NS_LITERAL_STRING(""));
}
NS_IMETHODIMP nsAbLDAPReplicationQuery::QueryAllEntries()
@ -180,12 +193,10 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::QueryAllEntries()
if (!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_OK;
// get the search filter associated with the directory server url;
//
nsXPIDLCString urlFilter;
rv = mURL->GetFilter(getter_Copies(urlFilter));
nsresult rv = mURL->GetFilter(getter_Copies(urlFilter));
if (NS_FAILED(rv))
return rv;
@ -231,6 +242,9 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::Done(PRBool aSuccess)
if (NS_SUCCEEDED(rv))
replicationService->Done(aSuccess);
if (aSuccess)
DIR_SavePrefsForOneServer(mDirServer);
return rv;
}
@ -268,13 +282,14 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::GetReplicationURL(nsILDAPURL * *aReplica
return NS_OK;
}
NS_IMETHODIMP nsAbLDAPReplicationQuery::GetReplicationInfo(DIR_ReplicationInfo * *aReplicationInfo)
NS_IMETHODIMP nsAbLDAPReplicationQuery::GetReplicationServerInfo(DIR_Server * *aReplicationServerInfo)
{
NS_ENSURE_ARG_POINTER(aReplicationInfo);
NS_ENSURE_ARG_POINTER(aReplicationServerInfo);
if (!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
*aReplicationInfo = mDirServer->replInfo;
*aReplicationServerInfo = mDirServer;
return NS_OK;
}

Просмотреть файл

@ -58,7 +58,6 @@ public:
virtual ~nsAbLDAPReplicationQuery();
nsresult InitLDAPData();
nsresult ConnectToLDAPServer(nsILDAPURL * aURL);
protected :
// pointer to interfaces used by this object

Просмотреть файл

@ -42,9 +42,12 @@
#include "nsAbBaseCID.h"
#include "nsIWebProgressListener.h"
#include "nsAbLDAPChangeLogQuery.h"
#include "nsIAbLDAPReplicationData.h"
/*** implementation of the service ******/
NS_IMPL_THREADSAFE_ISUPPORTS1(nsAbLDAPReplicationService, nsIAbLDAPReplicationService)
NS_IMPL_ISUPPORTS1(nsAbLDAPReplicationService, nsIAbLDAPReplicationService)
nsAbLDAPReplicationService::nsAbLDAPReplicationService()
: mReplicating(PR_FALSE)
@ -78,6 +81,14 @@ NS_IMETHODIMP nsAbLDAPReplicationService::StartReplication(const nsACString & aP
{
case nsIAbLDAPProcessReplicationData::kDefaultDownloadAll :
mQuery = do_CreateInstance(NS_ABLDAP_REPLICATIONQUERY_CONTRACTID, &rv);
break ;
case nsIAbLDAPProcessReplicationData::kChangeLogProtocol :
mQuery = do_CreateInstance (NS_ABLDAP_CHANGELOGQUERY_CONTRACTID, &rv);
break ;
default :
break;
}
if(NS_SUCCEEDED(rv) && mQuery)
{
rv = mQuery->Init(aPrefName, progressListener);
@ -91,13 +102,7 @@ NS_IMETHODIMP nsAbLDAPReplicationService::StartReplication(const nsACString & aP
}
}
}
break;
default :
break;
}
// this should come here only in case of an error, either when DoReplicationQuery errors out
// of if DecideProtocol returns an error.
if(progressListener && NS_FAILED(rv))
progressListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_STOP, PR_FALSE);
@ -139,8 +144,9 @@ NS_IMETHODIMP nsAbLDAPReplicationService::Done(PRBool aSuccess)
// if it exists ChangeLog protocol is supported.
PRInt32 nsAbLDAPReplicationService::DecideProtocol()
{
// currently only Replicate All is implemented
return nsIAbLDAPProcessReplicationData::kDefaultDownloadAll;
// do the changeLog, it will decide if there is a need to replicate all
// entries or only update existing DB and will do the approprite thing.
return nsIAbLDAPProcessReplicationData::kChangeLogProtocol;
}

Просмотреть файл

@ -2936,11 +2936,8 @@ nsresult nsAddrDatabase::CreateCard(nsIMdbRow* cardRow, mdb_id listRowID, nsIAbC
if(NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIAbCard> personCard;
nsCOMPtr<nsIAbMDBDirectory> dbm_dbDirectory(do_QueryInterface(m_dbDirectory,&rv));
if (NS_SUCCEEDED(rv) && dbm_dbDirectory) {
personCard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
}
nsCOMPtr<nsIAbMDBCard> dbpersonCard (do_QueryInterface(personCard, &rv));