From b139864590c01f9178e5105e13b5ebfa8129ec2d Mon Sep 17 00:00:00 2001 From: "sspitzer%netscape.com" Date: Tue, 21 May 2002 05:20:39 +0000 Subject: [PATCH] fix for bug #142940. add support to LDIF import / export for generic AB columns, like _AimScreenName. r=dmose, sr=bienvenu git-svn-id: svn://10.0.0.236/trunk@121916 18797224-902f-48f8-a5cc-f745e15eee43 --- .../addrbook/public/nsIAddrDatabase.idl | 14 +++++ .../mailnews/addrbook/src/nsAddrDatabase.cpp | 20 ++++-- .../mailnews/addrbook/src/nsAddrDatabase.h | 5 +- .../mailnews/addrbook/src/nsAddressBook.cpp | 61 +++++++++++++++++-- mozilla/mailnews/addrbook/src/nsAddressBook.h | 9 +-- .../import/text/src/nsTextAddress.cpp | 34 +++++++++++ 6 files changed, 127 insertions(+), 16 deletions(-) diff --git a/mozilla/mailnews/addrbook/public/nsIAddrDatabase.idl b/mozilla/mailnews/addrbook/public/nsIAddrDatabase.idl index 952654715c1..7fabf1474d6 100644 --- a/mozilla/mailnews/addrbook/public/nsIAddrDatabase.idl +++ b/mozilla/mailnews/addrbook/public/nsIAddrDatabase.idl @@ -208,4 +208,18 @@ interface nsIAddrDatabase : nsIAddrDBAnnouncer { */ void setCardValue(in nsIAbCard card, in string name, in wstring value, in boolean notify); wstring getCardValue(in nsIAbCard card, in string name); + + /** + * used for adding a string attributes to a row. + * the string attribute does not have to be a generic attribute + * (ex: _AimScreenName). used during LDIF and addressbook import. + * + * @param aRow + * The row we're adding the column to + * @param aColName + * The column name (example: _AimScreenName) + * @param aColValue + * The column value (example: jabroni316) + */ + [noscript] void addRowValue(in nsIMdbRow aRow, in ACString aColName, in AString aColValue); }; diff --git a/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp b/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp index 1a997899db3..73bc6707b68 100644 --- a/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp +++ b/mozilla/mailnews/addrbook/src/nsAddrDatabase.cpp @@ -2078,9 +2078,9 @@ void nsAddrDatabase::GetCharStringYarn(char* str, struct mdbYarn* strYarn) strYarn->mYarn_Form = 0; } -void nsAddrDatabase::GetStringYarn(nsString* str, struct mdbYarn* strYarn) +void nsAddrDatabase::GetStringYarn(const nsAString & aStr, struct mdbYarn* strYarn) { - strYarn->mYarn_Buf = ToNewCString(*str); + strYarn->mYarn_Buf = ToNewUTF8String(aStr); strYarn->mYarn_Size = PL_strlen((const char *) strYarn->mYarn_Buf) + 1; strYarn->mYarn_Fill = strYarn->mYarn_Size - 1; strYarn->mYarn_Form = 0; @@ -2106,12 +2106,12 @@ nsresult nsAddrDatabase::AddCharStringColumn(nsIMdbRow* cardRow, mdb_column inCo return (err == NS_OK) ? NS_OK : NS_ERROR_FAILURE; } -nsresult nsAddrDatabase::AddStringColumn(nsIMdbRow* cardRow, mdb_column inColumn, nsString* str) +nsresult nsAddrDatabase::AddStringColumn(nsIMdbRow* aCardRow, mdb_column aInColumn, const nsAString & aStr) { struct mdbYarn yarn; - GetStringYarn(str, &yarn); - mdb_err err = cardRow->AddColumn(GetEnv(), inColumn, &yarn); + GetStringYarn(aStr, &yarn); + mdb_err err = aCardRow->AddColumn(GetEnv(), aInColumn, &yarn); return (err == NS_OK) ? NS_OK : NS_ERROR_FAILURE; } @@ -3140,6 +3140,16 @@ NS_IMETHODIMP nsAddrDatabase::GetCardFromAttribute(nsIAbDirectory *aDirectory, c return rv; } +NS_IMETHODIMP nsAddrDatabase::AddRowValue(nsIMdbRow *aRow, const nsACString & aColName, const nsAString & aColValue) +{ + mdb_token token; + GetStore()->StringToToken(GetEnv(), PromiseFlatCString(aColName).get(), &token); + + nsresult rv = AddStringColumn(aRow, token, aColValue); + NS_ENSURE_SUCCESS(rv,rv); + return NS_OK; +} + NS_IMETHODIMP nsAddrDatabase::GetDirectoryName(PRUnichar **name) { if (m_dbDirectory && name) diff --git a/mozilla/mailnews/addrbook/src/nsAddrDatabase.h b/mozilla/mailnews/addrbook/src/nsAddrDatabase.h index 10a2342e8a8..0fbccb0e5b1 100644 --- a/mozilla/mailnews/addrbook/src/nsAddrDatabase.h +++ b/mozilla/mailnews/addrbook/src/nsAddrDatabase.h @@ -232,6 +232,7 @@ public: NS_IMETHOD SetCardValue(nsIAbCard *card, const char *name, const PRUnichar *value, PRBool notify); NS_IMETHOD GetCardValue(nsIAbCard *card, const char *name, PRUnichar **value); + NS_IMETHOD AddRowValue(nsIMdbRow *aRow, const nsACString & aColName, const nsAString & aColValue); // nsAddrDatabase methods: @@ -277,10 +278,10 @@ protected: void YarnToUInt32(struct mdbYarn *yarn, PRUint32 *pResult); void GetCharStringYarn(char* str, struct mdbYarn* strYarn); - void GetStringYarn(nsString* str, struct mdbYarn* strYarn); + void GetStringYarn(const nsAString & aStr, struct mdbYarn* strYarn); void GetIntYarn(PRUint32 nValue, struct mdbYarn* intYarn); nsresult AddCharStringColumn(nsIMdbRow* cardRow, mdb_column inColumn, const char* str); - nsresult AddStringColumn(nsIMdbRow* cardRow, mdb_column inColumn, nsString* str); + nsresult AddStringColumn(nsIMdbRow* aCardRow, mdb_column aInColumn, const nsAString & aStr); nsresult AddIntColumn(nsIMdbRow* cardRow, mdb_column inColumn, PRUint32 nValue); nsresult AddBoolColumn(nsIMdbRow* cardRow, mdb_column inColumn, PRBool bValue); nsresult GetStringColumn(nsIMdbRow *cardRow, mdb_token outToken, nsString& str); diff --git a/mozilla/mailnews/addrbook/src/nsAddressBook.cpp b/mozilla/mailnews/addrbook/src/nsAddressBook.cpp index 1c094718928..9c8d8b9ec21 100644 --- a/mozilla/mailnews/addrbook/src/nsAddressBook.cpp +++ b/mozilla/mailnews/addrbook/src/nsAddressBook.cpp @@ -72,6 +72,8 @@ #include "nsSpecialSystemDirectory.h" #include "nsIFilePicker.h" #include "nsIPref.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" #include "nsVoidArray.h" #include "nsIAbCard.h" #include "nsIAbMDBCard.h" @@ -110,7 +112,6 @@ struct ExportAttributesTableStruct // XXX todo, merge with what's in nsAbLDAPProperties.cpp, so we can // use this for LDAP and LDIF export -// XXX todo what about _AimScreenName, or other generic columns? // // here's how we're coming up with the ldapPropertyName values // if they are specified in RFC 2798, use them @@ -1595,6 +1596,18 @@ nsAddressBook::ExportDirectoryToLDIF(nsIAbDirectory *aDirectory, nsILocalFile *a // ldif doesn't export mutliple addresses } } + + nsCString optionalLDIF; + rv = GetOptionalLDIFForCard(card, optionalLDIF); + NS_ENSURE_SUCCESS(rv,rv); + + length = optionalLDIF.Length(); + if (length) { + rv = outputStream->Write(optionalLDIF.get(), length, &writeCount); + NS_ENSURE_SUCCESS(rv,rv); + if (length != writeCount) + return NS_ERROR_FAILURE; + } // write out the linebreak that seperates the cards rv = outputStream->Write(LDIF_LINEBREAK, LDIF_LINEBREAK_LEN, &writeCount); @@ -1614,7 +1627,7 @@ nsAddressBook::ExportDirectoryToLDIF(nsIAbDirectory *aDirectory, nsILocalFile *a return NS_OK; } -nsresult nsAddressBook::AppendLDIFForMailList(nsIAbCard *aCard, nsAFlatCString &aResult) +nsresult nsAddressBook::AppendLDIFForMailList(nsIAbCard *aCard, nsACString &aResult) { nsresult rv; nsXPIDLString attrValue; @@ -1690,7 +1703,7 @@ nsresult nsAddressBook::AppendLDIFForMailList(nsIAbCard *aCard, nsAFlatCString & return NS_OK; } -nsresult nsAddressBook::AppendDNForCard(const char *aProperty, nsIAbCard *aCard, nsAFlatCString &aResult) +nsresult nsAddressBook::AppendDNForCard(const char *aProperty, nsIAbCard *aCard, nsACString &aResult) { nsXPIDLString email; nsXPIDLString displayName; @@ -1719,7 +1732,7 @@ nsresult nsAddressBook::AppendDNForCard(const char *aProperty, nsIAbCard *aCard, return rv; } -nsresult nsAddressBook::AppendBasicLDIFForCard(nsIAbCard *aCard, nsAFlatCString &aResult) +nsresult nsAddressBook::AppendBasicLDIFForCard(nsIAbCard *aCard, nsACString &aResult) { nsresult rv = AppendDNForCard("dn", aCard, aResult); NS_ENSURE_SUCCESS(rv,rv); @@ -1755,7 +1768,7 @@ PRBool nsAddressBook::IsSafeLDIFString(const PRUnichar *aStr) return PR_TRUE; } -nsresult nsAddressBook::AppendProperty(const char *aProperty, const PRUnichar *aValue, nsAFlatCString &aResult) +nsresult nsAddressBook::AppendProperty(const char *aProperty, const PRUnichar *aValue, nsACString &aResult) { NS_ENSURE_ARG_POINTER(aValue); @@ -1777,5 +1790,43 @@ nsresult nsAddressBook::AppendProperty(const char *aProperty, const PRUnichar *a return NS_OK; } + +nsresult nsAddressBook::GetOptionalLDIFForCard(nsIAbCard *aCard, nsACString &aResult) +{ + nsresult rv; + nsCOMPtr dbcard = do_QueryInterface(aCard, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); + + nsCOMPtr prefBranch; + rv = prefs->GetBranch(nsnull, getter_AddRefs(prefBranch)); + NS_ENSURE_SUCCESS(rv,rv); + + NS_NAMED_LITERAL_CSTRING(kOptionalLDIFExportMapPrefix, "mail.addr_book.export_ldif_map."); + PRUint32 i, prefCount, prefixLen=kOptionalLDIFExportMapPrefix.Length(); + char **prefNames; + + rv = prefBranch->GetChildList(kOptionalLDIFExportMapPrefix.get(), &prefCount, &prefNames); + if (NS_SUCCEEDED(rv) && prefCount > 0) { + for (i = 0; i < prefCount; i++) { + nsXPIDLString genericValue; + rv = dbcard->GetStringAttribute(prefNames[i]+prefixLen, getter_Copies(genericValue)); + if (NS_SUCCEEDED(rv) && !genericValue.IsEmpty()) { + nsXPIDLCString mapValue; + rv = prefBranch->GetCharPref(prefNames[i], getter_Copies(mapValue)); + if (NS_SUCCEEDED(rv) && mapValue.Length()) { + rv = AppendProperty(mapValue.get(), genericValue.get(), aResult); + aResult += LDIF_LINEBREAK; + } + } + } + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames); + } + return NS_OK; +} + + CMDLINEHANDLER_IMPL(nsAddressBook,"-addressbook","general.startup.addressbook","chrome://messenger/content/addressbook/addressbook.xul","Start with the addressbook.",NS_ADDRESSBOOKSTARTUPHANDLER_CONTRACTID,"Addressbook Startup Handler",PR_FALSE,"", PR_TRUE) diff --git a/mozilla/mailnews/addrbook/src/nsAddressBook.h b/mozilla/mailnews/addrbook/src/nsAddressBook.h index 6c70ba98af2..b0ef069e3d1 100644 --- a/mozilla/mailnews/addrbook/src/nsAddressBook.h +++ b/mozilla/mailnews/addrbook/src/nsAddressBook.h @@ -77,10 +77,11 @@ private: nsIDocShell *mDocShell; // weak reference nsresult ExportDirectoryToDelimitedText(nsIAbDirectory *aDirectory, const char *aDelim, PRUint32 aDelimLen, nsILocalFile *aLocalFile); nsresult ExportDirectoryToLDIF(nsIAbDirectory *aDirectory, nsILocalFile *aLocalFile); - nsresult AppendLDIFForMailList(nsIAbCard *aCard, nsAFlatCString &aResult); - nsresult AppendDNForCard(const char *aProperty, nsIAbCard *aCard, nsAFlatCString &aResult); - nsresult AppendBasicLDIFForCard(nsIAbCard *aCard, nsAFlatCString &aResult); - nsresult AppendProperty(const char *aProperty, const PRUnichar *aValue, nsAFlatCString &aResult); + nsresult AppendLDIFForMailList(nsIAbCard *aCard, nsACString &aResult); + nsresult AppendDNForCard(const char *aProperty, nsIAbCard *aCard, nsACString &aResult); + nsresult AppendBasicLDIFForCard(nsIAbCard *aCard, nsACString &aResult); + nsresult AppendProperty(const char *aProperty, const PRUnichar *aValue, nsACString &aResult); + nsresult GetOptionalLDIFForCard(nsIAbCard *aCard, nsACString &aResult); PRBool IsSafeLDIFString(const PRUnichar *aStr); }; diff --git a/mozilla/mailnews/import/text/src/nsTextAddress.cpp b/mozilla/mailnews/import/text/src/nsTextAddress.cpp index 30cc261288b..0ada60ef7e7 100644 --- a/mozilla/mailnews/import/text/src/nsTextAddress.cpp +++ b/mozilla/mailnews/import/text/src/nsTextAddress.cpp @@ -25,6 +25,8 @@ #include "nsAbBaseCID.h" #include "nsIAbCard.h" #include "nsReadableUtils.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" static NS_DEFINE_CID(kAbCardPropertyCID, NS_ABCARDPROPERTY_CID); @@ -675,6 +677,9 @@ nsresult nsTextAddress::IsLDIFFile( nsIFileSpec *pSrc, PRBool *pIsLDIF) #define IS_SPACE(VAL) \ (((((intn)(VAL)) & 0x7f) == ((intn)(VAL))) && isspace((intn)(VAL)) ) +// XXX TODO fix me +// use the NSPR base64 library. see plbase64.h +// see bug #145367 static unsigned char b642nib[0x80] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -699,6 +704,7 @@ static unsigned char b642nib[0x80] = { * into components "type" and "value". if a double colon separates type from * value, then value is encoded in base 64, and parse_line un-decodes it * (in place) before returning. + * in LDIF, non-ASCII data is treated as base64 encoded UTF-8 */ nsresult nsTextAddress::str_parse_line( @@ -1141,6 +1147,34 @@ void nsTextAddress::AddLdifColToDatabase(nsIMdbRow* newRow, char* typeSlot, char m_database->AddHomeZipCode(newRow, column.get()); else if (colType.Equals(MOZ_AB_LDIF_PREFIX "homecountryname")) m_database->AddHomeCountry(newRow, column.get()); + else { + // handle all the optional LDIF attributes + // like mozillaaimscreenname (mozillaAimScreenName) + // + // note, all optional LDIF attributes begin with the "mozilla" prefix + // see bug #119360. that's why the import code to handle them + // is under the "m" clause. + nsresult rv; + nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get pref service"); + if (NS_FAILED(rv)) + break; + + nsCOMPtr prefBranch; + rv = prefs->GetBranch(nsnull, getter_AddRefs(prefBranch)); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get pref branch"); + if (NS_FAILED(rv)) + break; + + nsCAutoString prefName; + prefName = NS_LITERAL_CSTRING("mail.addr_book.import_ldif_map.") + colType; + + nsXPIDLCString columnName; + rv = prefBranch->GetCharPref(prefName.get(), getter_Copies(columnName)); + if (NS_SUCCEEDED(rv) && columnName.Length()) { + m_database->AddRowValue(newRow, columnName, NS_ConvertUTF8toUCS2(column)); + } + } break; // 'm' case 'n':