NS_IMETHODIMP nsAbLDAPCard::SetMetaProperties(nsILDAPMessage *aMessage) { NS_ENSURE_ARG_POINTER(aMessage); // Get DN nsAutoCString dn; nsresult rv = aMessage->GetDn(dn); NS_ENSURE_SUCCESS(rv, rv); SetDn(dn); // Get the list of set attributes CharPtrArrayGuard attrs; rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr()); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString attr; m_attributes.Clear(); for (uint32_t i = 0; i < attrs.GetSize(); ++i) { attr.Assign(nsDependentCString(attrs[i])); ToLowerCase(attr); m_attributes.AppendElement(attr); } // Get the objectClass values m_objectClass.Clear(); PRUnicharPtrArrayGuard vals; rv = aMessage->GetValues("objectClass", vals.GetSizeAddr(), vals.GetArrayAddr()); // objectClass is not always included in search result entries and // nsILDAPMessage::GetValues returns NS_ERROR_LDAP_DECODING_ERROR if the // requested attribute doesn't exist. if (rv == NS_ERROR_LDAP_DECODING_ERROR) return NS_OK; NS_ENSURE_SUCCESS(rv, rv); nsAutoCString oclass; for (uint32_t i = 0; i < vals.GetSize(); ++i) { oclass.Assign(NS_LossyConvertUTF16toASCII(nsDependentString(vals[i]))); ToLowerCase(oclass); m_objectClass.AppendElement(oclass); } return NS_OK; }
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")) CopyUTF16toUTF8(vals[0], mRootDSEEntry.changeLogDN); if (!PL_strcasecmp(attrs[i], "firstChangeNumber")) mRootDSEEntry.firstChangeNumber = atol(NS_LossyConvertUTF16toASCII(vals[0]).get()); if (!PL_strcasecmp(attrs[i], "lastChangeNumber")) mRootDSEEntry.lastChangeNumber = atol(NS_LossyConvertUTF16toASCII(vals[0]).get()); if (!PL_strcasecmp(attrs[i], "dataVersion")) CopyUTF16toUTF8(vals[0], mRootDSEEntry.dataVersion); } } PRInt32 lastChangeNumber; mDirectory->GetLastChangeNumber(&lastChangeNumber); if ((mRootDSEEntry.lastChangeNumber > 0) && (lastChangeNumber < mRootDSEEntry.lastChangeNumber) && (lastChangeNumber > mRootDSEEntry.firstChangeNumber)) mUseChangeLog = PR_TRUE; if (mRootDSEEntry.lastChangeNumber && (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::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_ConvertUTF16toUTF8(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: // Do not check the return here since delete may fail if // entry deleted in changelog does not exist in DB // for e.g if the user specifies a filter, so go next entry DeleteCard(targetDN); break; case ENTRY_MODIFY: // For modify, delete 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, // e.g. in case a filter is specified. return NS_OK; }
nsresult nsAbQueryLDAPMessageListener::OnLDAPMessageSearchEntry (nsILDAPMessage *aMessage, nsIAbDirectoryQueryResult** result) { nsresult rv; if (!mDirectoryQuery) return NS_ERROR_NULL_POINTER; // the address book fields that we'll be asking for CharPtrArrayGuard properties; rv = mQueryArguments->GetReturnProperties (properties.GetSizeAddr(), properties.GetArrayAddr()); NS_ENSURE_SUCCESS(rv, rv); // the map for translating between LDAP attrs <-> addrbook fields nsCOMPtr<nsISupports> iSupportsMap; rv = mQueryArguments->GetTypeSpecificArg(getter_AddRefs(iSupportsMap)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIAbLDAPAttributeMap> map = do_QueryInterface(iSupportsMap, &rv); NS_ENSURE_SUCCESS(rv, rv); // set up variables for handling the property values to be returned nsCOMPtr<nsISupportsArray> propertyValues; nsCOMPtr<nsIAbDirectoryQueryPropertyValue> propertyValue; rv = NS_NewISupportsArray(getter_AddRefs(propertyValues)); NS_ENSURE_SUCCESS(rv, rv); if (!strcmp(properties[0], "card:nsIAbCard")) { // Meta property nsCAutoString dn; rv = aMessage->GetDn (dn); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIAbCard> card; rv = mDirectoryQuery->CreateCard (mUrl, dn.get(), getter_AddRefs (card)); NS_ENSURE_SUCCESS(rv, rv); rv = map->SetCardPropertiesFromLDAPMessage(aMessage, card); NS_ENSURE_SUCCESS(rv, rv); propertyValue = new nsAbDirectoryQueryPropertyValue(properties[0], card); if (!propertyValue) return NS_ERROR_OUT_OF_MEMORY; rv = propertyValues->AppendElement(propertyValue); NS_ENSURE_SUCCESS(rv, rv); } else { for (PRUint32 i = 0; i < properties.GetSize(); i++) { // this is the precedence order list of attrs for this property CharPtrArrayGuard attrs; rv = map->GetAttributes(nsDependentCString(properties[i]), attrs.GetSizeAddr(), attrs.GetArrayAddr()); // if there are no attrs for this property, just move on if (NS_FAILED(rv) || !strlen(attrs[0])) { continue; } // iterate through list, until first property found for (PRUint32 j=0; j < attrs.GetSize(); j++) { // try and get the values for this ldap attribute PRUnicharPtrArrayGuard vals; rv = aMessage->GetValues(attrs[j], vals.GetSizeAddr(), vals.GetArrayAddr()); if (NS_SUCCEEDED(rv) && vals.GetSize()) { propertyValue = new nsAbDirectoryQueryPropertyValue( properties[i], vals[0]); if (!propertyValue) { return NS_ERROR_OUT_OF_MEMORY; } (void)propertyValues->AppendElement (propertyValue); break; } } } } return QueryResultStatus (propertyValues, result, nsIAbDirectoryQueryResult::queryResultMatch); }