1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * Copyright 2008 by Sun Microsystems, Inc.
6 * OpenOffice.org - a multi-platform office productivity suite
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
28 ************************************************************************/
30 // MARKER(update_precomp.py): autogen include statement, do not remove
31 #include "precompiled_connectivity.hxx"
33 #include <rtl/strbuf.hxx>
34 // keep this include at the beginning. Some of the other includes seems to inject a symbol "l" into the
35 // global namespace, which leads to a compiler warning in strbuf.hxx, about some parameters named "l"
36 // hiding objects "in an outer scope".
38 #include "MLdapAttributeMap.hxx"
39 #include "MTypeConverter.hxx"
40 #include "MQueryHelper.hxx"
42 #include <tools/diagnose_ex.h>
46 //........................................................................
47 namespace connectivity
{ namespace mozab
{
48 //........................................................................
50 //====================================================================
52 //====================================================================
55 typedef nsresult (NS_STDCALL
nsIAbCard::*CardPropertyGetter
)( PRUnichar
** aFirstName
);
56 typedef nsresult (NS_STDCALL
nsIAbCard::*CardPropertySetter
)( const PRUnichar
* aFirstName
);
57 struct CardPropertyData
59 const sal_Char
* pLDAPAttributeList
;
60 CardPropertyGetter PropGetter
;
61 CardPropertySetter PropSetter
;
64 :pLDAPAttributeList( NULL
)
69 CardPropertyData( const sal_Char
* _pLDAPAttributeList
, CardPropertyGetter _PropGetter
, CardPropertySetter _PropSetter
)
70 :pLDAPAttributeList( _pLDAPAttributeList
)
71 ,PropGetter( _PropGetter
)
72 ,PropSetter( _PropSetter
)
77 typedef ::std::hash_map
< ::rtl::OString
, CardPropertyData
, ::rtl::OStringHash
> MapPropertiesToAttributes
;
79 #define DEF_CARD_ACCESS( PropertyName ) \
80 &nsIAbCard::Get##PropertyName, &nsIAbCard::Set##PropertyName
82 static const MapPropertiesToAttributes
& lcl_getPropertyMap()
84 static MapPropertiesToAttributes aMap
;
89 const sal_Char
* pAsciiPropertyName
;
90 const sal_Char
* pAsciiAttrributeList
;
91 CardPropertyGetter PropGetter
;
92 CardPropertySetter PropSetter
;
94 const MapEntry aEntries
[] = {
95 { "FirstName", "givenname", DEF_CARD_ACCESS( FirstName
) },
96 { "LastName", "sn,surnname", DEF_CARD_ACCESS( LastName
) },
97 { "DisplayName", "cn,commonname,displayname", DEF_CARD_ACCESS( DisplayName
) },
98 { "NickName", "xmozillanickname", DEF_CARD_ACCESS( NickName
) },
99 { "PrimaryEmail", "mail", DEF_CARD_ACCESS( PrimaryEmail
) },
100 { "SecondEmail", "xmozillasecondemail", DEF_CARD_ACCESS( SecondEmail
) },
101 { "WorkPhone", "telephonenumber", DEF_CARD_ACCESS( WorkPhone
) },
102 { "HomePhone", "homephone", DEF_CARD_ACCESS( HomePhone
) },
103 { "FaxNumber", "fax,facsimiletelephonenumber", DEF_CARD_ACCESS( FaxNumber
) },
104 { "PagerNumber", "pager,pagerphone", DEF_CARD_ACCESS( PagerNumber
) },
105 { "CellularNumber", "mobile,cellphone,carphone", DEF_CARD_ACCESS( CellularNumber
) },
106 { "HomeAddress", "homepostaladdress,mozillaHomeStreet", DEF_CARD_ACCESS( HomeAddress
) },
107 { "HomeAddress2", "mozillaHomeStreet2", DEF_CARD_ACCESS( HomeAddress2
) },
108 { "HomeCity", "homelocality,mozillaHomeLocalityName", DEF_CARD_ACCESS( HomeCity
) },
109 { "HomeState", "homeregion,mozillaHomeState", DEF_CARD_ACCESS( HomeState
) },
110 { "HomeZipCode", "homepostalcode,mozillaHomePostalCode", DEF_CARD_ACCESS( HomeZipCode
) },
111 { "HomeCountry", "homecountryname,mozillaHomeCountryName", DEF_CARD_ACCESS( HomeCountry
) },
112 { "WorkAddress", "postofficebox,streetaddress,streetaddress1", DEF_CARD_ACCESS( WorkAddress
) },
113 { "WorkAddress2", "streetaddress2", DEF_CARD_ACCESS( WorkAddress2
) },
114 { "WorkCity", "l,locality", DEF_CARD_ACCESS( WorkCity
) },
115 { "WorkState", "st,region", DEF_CARD_ACCESS( WorkState
) },
116 { "WorkZipCode", "postalcode,zip", DEF_CARD_ACCESS( WorkZipCode
) },
117 { "WorkCountry", "countryname", DEF_CARD_ACCESS( WorkCountry
) },
118 { "JobTitle", "title", DEF_CARD_ACCESS( JobTitle
) },
119 { "Department", "ou,orgunit,department,departmentnumber", DEF_CARD_ACCESS( Department
) },
120 { "Company", "o,company", DEF_CARD_ACCESS( Company
) },
121 { "WebPage1", "workurl", DEF_CARD_ACCESS( WebPage1
) },
122 { "WebPage2", "homeurl", DEF_CARD_ACCESS( WebPage2
) },
123 { "BirthYear", "birthyear", DEF_CARD_ACCESS( BirthYear
) },
124 { "BirthMonth", "birthmonth", DEF_CARD_ACCESS( BirthMonth
) },
125 { "BirthYear", "birthday", DEF_CARD_ACCESS( BirthDay
) },
126 { "Custom1", "custom1", DEF_CARD_ACCESS( Custom1
) },
127 { "Custom2", "custom2", DEF_CARD_ACCESS( Custom2
) },
128 { "Custom3", "custom3", DEF_CARD_ACCESS( Custom3
) },
129 { "Custom4", "custom4", DEF_CARD_ACCESS( Custom4
) },
130 { "Notes", "notes,description", DEF_CARD_ACCESS( Notes
) },
131 { "PreferMailFormat", "xmozillausehtmlmail", NULL
, NULL
},
132 { NULL
, NULL
, NULL
, NULL
}
134 const MapEntry
* loop
= aEntries
;
135 while ( loop
->pAsciiPropertyName
)
137 aMap
[ ::rtl::OString( loop
->pAsciiPropertyName
) ] =
138 CardPropertyData( loop
->pAsciiAttrributeList
, loop
->PropGetter
, loop
->PropSetter
);
146 //====================================================================
147 //= AttributeMap_Data
148 //====================================================================
149 struct AttributeMap_Data
153 //====================================================================
154 //= MLdapAttributeMap
155 //====================================================================
156 // -------------------------------------------------------------------
157 MLdapAttributeMap::MLdapAttributeMap()
158 :m_pData( new AttributeMap_Data
)
162 // -------------------------------------------------------------------
163 MLdapAttributeMap::~MLdapAttributeMap()
167 // -------------------------------------------------------------------
168 NS_IMPL_THREADSAFE_ISUPPORTS1( MLdapAttributeMap
, nsIAbLDAPAttributeMap
)
170 // -------------------------------------------------------------------
171 NS_IMETHODIMP
MLdapAttributeMap::GetAttributeList(const nsACString
& aProperty
, nsACString
& _retval
)
173 ::rtl::OString
sProperty( MTypeConverter::nsACStringToOString( aProperty
) );
175 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
176 MapPropertiesToAttributes::const_iterator pos
= rPropertyMap
.find( sProperty
);
178 if ( pos
== rPropertyMap
.end() )
180 _retval
.SetIsVoid( PR_TRUE
);
184 MTypeConverter::asciiToNsACString( pos
->second
.pLDAPAttributeList
, _retval
);
190 // -------------------------------------------------------------------
191 NS_IMETHODIMP
MLdapAttributeMap::GetAttributes(const nsACString
& aProperty
, PRUint32
* aCount
, char*** aAttrs
)
193 OSL_ENSURE( false, "MLdapAttributeMap::GetAttributes: not implemented!" );
197 return NS_ERROR_NOT_IMPLEMENTED
;
200 // -------------------------------------------------------------------
201 NS_IMETHODIMP
MLdapAttributeMap::GetFirstAttribute(const nsACString
& aProperty
, nsACString
& _retval
)
203 ::rtl::OString
sProperty( MTypeConverter::nsACStringToOString( aProperty
) );
205 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
206 MapPropertiesToAttributes::const_iterator pos
= rPropertyMap
.find( sProperty
);
208 if ( pos
== rPropertyMap
.end() )
210 _retval
.SetIsVoid( PR_TRUE
);
214 sal_Int32
tokenPos(0);
215 ::rtl::OString
sAttributeList( pos
->second
.pLDAPAttributeList
);
216 MTypeConverter::asciiToNsACString( sAttributeList
.getToken( 0, ',', tokenPos
).getStr(), _retval
);
222 // -------------------------------------------------------------------
223 NS_IMETHODIMP
MLdapAttributeMap::SetAttributeList(const nsACString
& aProperty
, const nsACString
& aAttributeList
, PRBool allowInconsistencies
)
225 OSL_ENSURE( false, "MLdapAttributeMap::SetAttributeList: not implemented!" );
227 (void)aAttributeList
;
228 (void)allowInconsistencies
;
229 return NS_ERROR_NOT_IMPLEMENTED
;
232 // -------------------------------------------------------------------
233 NS_IMETHODIMP
MLdapAttributeMap::GetProperty(const nsACString
& aAttribute
, nsACString
& _retval
)
235 OSL_ENSURE( false, "MLdapAttributeMap::GetProperty: not implemented!" );
238 return NS_ERROR_NOT_IMPLEMENTED
;
241 // -------------------------------------------------------------------
242 NS_IMETHODIMP
MLdapAttributeMap::GetAllCardAttributes(nsACString
& _retval
)
244 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
246 ::rtl::OStringBuffer aAllAttributes
;
247 for ( MapPropertiesToAttributes::const_iterator loop
= rPropertyMap
.begin();
248 loop
!= rPropertyMap
.end();
252 aAllAttributes
.append( loop
->second
.pLDAPAttributeList
);
253 if ( loop
!= rPropertyMap
.end() )
254 aAllAttributes
.append( ',' );
257 MTypeConverter::asciiToNsACString( aAllAttributes
.getStr(), _retval
);
261 // -------------------------------------------------------------------
262 NS_IMETHODIMP
MLdapAttributeMap::CheckState(void)
264 // we do not allow modifying the map, so we're always in a valid state
268 // -------------------------------------------------------------------
269 NS_IMETHODIMP
MLdapAttributeMap::SetFromPrefs(const nsACString
& aPrefBranchName
)
271 OSL_ENSURE( false, "MLdapAttributeMap::SetFromPrefs: not implemented!" );
272 (void)aPrefBranchName
;
273 return NS_ERROR_NOT_IMPLEMENTED
;
276 // -------------------------------------------------------------------
277 NS_IMETHODIMP
MLdapAttributeMap::SetCardPropertiesFromLDAPMessage(nsILDAPMessage
* aMessage
, nsIAbCard
* aCard
)
279 NS_ENSURE_ARG_POINTER( aMessage
);
280 NS_ENSURE_ARG_POINTER( aCard
);
282 // in case that's not present in the LDAP message: set the "preferred mail format" to "none"
283 aCard
->SetPreferMailFormat( nsIAbPreferMailFormat::unknown
);
285 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
286 for ( MapPropertiesToAttributes::const_iterator prop
= rPropertyMap
.begin();
287 prop
!= rPropertyMap
.end();
291 // split the list of attributes for the current property
292 ::rtl::OString
sAttributeList( prop
->second
.pLDAPAttributeList
);
293 ::rtl::OString sAttribute
;
295 sal_Int32 tokenPos
= 0;
296 while ( tokenPos
!= -1 )
298 sAttribute
= sAttributeList
.getToken( 0, ',', tokenPos
);
300 // retrieve the values for the current attribute
301 PRUint32 valueCount
= 0;
302 PRUnichar
** values
= NULL
;
303 nsresult rv
= aMessage
->GetValues( sAttribute
.getStr(), &valueCount
, &values
);
304 if ( NS_FAILED( rv
) )
305 // try the next attribute
310 CardPropertySetter propSetter
= prop
->second
.PropSetter
;
311 OSL_ENSURE( propSetter
,
312 "MLdapAttributeMap::SetCardPropertiesFromLDAPMessage: "
313 "unexpected: could retrieve an attribute value, but have no setter for it!" );
316 (aCard
->*propSetter
)( values
[0] );
319 // we're done with this property - no need to handle the remaining attributes which
328 // -------------------------------------------------------------------
331 struct PreferMailFormatType
333 const sal_Char
* description
;
336 PreferMailFormatType()
338 ,formatType( nsIAbPreferMailFormat::unknown
)
342 PreferMailFormatType( const sal_Char
* _description
, PRUint32 _formatType
)
343 :description( _description
)
344 ,formatType( _formatType
)
349 static const PreferMailFormatType
* lcl_getMailFormatTypes()
351 static const PreferMailFormatType aMailFormatTypes
[] =
353 PreferMailFormatType( "text/plain", nsIAbPreferMailFormat::plaintext
),
354 PreferMailFormatType( "text/html", nsIAbPreferMailFormat::html
),
355 PreferMailFormatType( "unknown", nsIAbPreferMailFormat::unknown
),
356 PreferMailFormatType()
358 return aMailFormatTypes
;
362 // -------------------------------------------------------------------
363 void MLdapAttributeMap::fillCardFromResult( nsIAbCard
& _card
, const MQueryHelperResultEntry
& _result
)
365 _card
.SetPreferMailFormat( nsIAbPreferMailFormat::unknown
);
367 ::rtl::OUString resultValue
;
369 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
370 for ( MapPropertiesToAttributes::const_iterator prop
= rPropertyMap
.begin();
371 prop
!= rPropertyMap
.end();
375 resultValue
= _result
.getValue( prop
->first
);
377 CardPropertySetter propSetter
= prop
->second
.PropSetter
;
380 // PRUnichar != sal_Unicode in mingw
381 (_card
.*propSetter
)( reinterpret_cast_mingw_only
<const PRUnichar
*>(resultValue
.getStr()) );
385 if ( prop
->first
.equals( "PreferMailFormat" ) )
387 unsigned int format
= nsIAbPreferMailFormat::unknown
;
388 const PreferMailFormatType
* pMailFormatType
= lcl_getMailFormatTypes();
389 while ( pMailFormatType
->description
)
391 if ( resultValue
.equalsAscii( pMailFormatType
->description
) )
393 format
= pMailFormatType
->formatType
;
398 _card
.SetPreferMailFormat(format
);
401 OSL_ENSURE( false, "MLdapAttributeMap::fillCardFromResult: unexpected property without default setters!" );
406 // -------------------------------------------------------------------
407 void MLdapAttributeMap::fillResultFromCard( MQueryHelperResultEntry
& _result
, nsIAbCard
& _card
)
410 ::rtl::OUString resultValue
;
412 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
413 for ( MapPropertiesToAttributes::const_iterator prop
= rPropertyMap
.begin();
414 prop
!= rPropertyMap
.end();
418 CardPropertyGetter propGetter
= prop
->second
.PropGetter
;
421 (_card
.*propGetter
)( getter_Copies( value
) );
423 nsAutoString
temp( value
);
424 MTypeConverter::nsStringToOUString( temp
, resultValue
);
428 if ( prop
->first
.equals( "PreferMailFormat" ) )
430 unsigned int format
= nsIAbPreferMailFormat::unknown
;
431 _card
.GetPreferMailFormat( &format
);
432 const PreferMailFormatType
* pMailFormatType
= lcl_getMailFormatTypes();
433 while ( pMailFormatType
->description
)
435 if ( format
== pMailFormatType
->formatType
)
437 resultValue
= ::rtl::OUString::createFromAscii( pMailFormatType
->description
);
444 OSL_ENSURE( false, "MLdapAttributeMap::fillResultFromCard: unexpected property without default getters!" );
447 _result
.insert( prop
->first
, resultValue
);
451 //........................................................................
452 } } // namespace connectivity::mozab
453 //........................................................................