1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <rtl/strbuf.hxx>
22 // keep this include at the beginning. Some of the other includes seems to inject a symbol "l" into the
23 // global namespace, which leads to a compiler warning in strbuf.hxx, about some parameters named "l"
24 // hiding objects "in an outer scope".
26 #include "MLdapAttributeMap.hxx"
27 #include "MTypeConverter.hxx"
28 #include "MQueryHelper.hxx"
30 #include <tools/diagnose_ex.h>
32 #include <unordered_map>
34 namespace connectivity
{ namespace mozab
{
38 typedef NS_STDCALL_FUNCPROTO(nsresult
, CardPropertyGetter
, nsIAbCard
, GetFirstName
, (PRUnichar
**));
39 typedef NS_STDCALL_FUNCPROTO(nsresult
, CardPropertySetter
, nsIAbCard
, SetFirstName
, (const PRUnichar
*));
40 struct CardPropertyData
42 const sal_Char
* pLDAPAttributeList
;
43 CardPropertyGetter PropGetter
;
44 CardPropertySetter PropSetter
;
47 :pLDAPAttributeList( NULL
)
52 CardPropertyData( const sal_Char
* _pLDAPAttributeList
, CardPropertyGetter _PropGetter
, CardPropertySetter _PropSetter
)
53 :pLDAPAttributeList( _pLDAPAttributeList
)
54 ,PropGetter( _PropGetter
)
55 ,PropSetter( _PropSetter
)
60 typedef std::unordered_map
< OString
, CardPropertyData
, OStringHash
> MapPropertiesToAttributes
;
62 #define DEF_CARD_ACCESS( PropertyName ) \
63 &nsIAbCard::Get##PropertyName, &nsIAbCard::Set##PropertyName
65 static const MapPropertiesToAttributes
& lcl_getPropertyMap()
67 static MapPropertiesToAttributes aMap
;
72 const sal_Char
* pAsciiPropertyName
;
73 const sal_Char
* pAsciiAttrributeList
;
74 CardPropertyGetter PropGetter
;
75 CardPropertySetter PropSetter
;
77 const MapEntry aEntries
[] = {
78 { "FirstName", "givenname", DEF_CARD_ACCESS( FirstName
) },
79 { "LastName", "sn,surnname", DEF_CARD_ACCESS( LastName
) },
80 { "DisplayName", "cn,commonname,displayname", DEF_CARD_ACCESS( DisplayName
) },
81 { "NickName", "xmozillanickname", DEF_CARD_ACCESS( NickName
) },
82 { "PrimaryEmail", "mail", DEF_CARD_ACCESS( PrimaryEmail
) },
83 { "SecondEmail", "xmozillasecondemail", DEF_CARD_ACCESS( SecondEmail
) },
84 { "WorkPhone", "telephonenumber", DEF_CARD_ACCESS( WorkPhone
) },
85 { "HomePhone", "homephone", DEF_CARD_ACCESS( HomePhone
) },
86 { "FaxNumber", "fax,facsimiletelephonenumber", DEF_CARD_ACCESS( FaxNumber
) },
87 { "PagerNumber", "pager,pagerphone", DEF_CARD_ACCESS( PagerNumber
) },
88 { "CellularNumber", "mobile,cellphone,carphone", DEF_CARD_ACCESS( CellularNumber
) },
89 { "HomeAddress", "homepostaladdress,mozillaHomeStreet", DEF_CARD_ACCESS( HomeAddress
) },
90 { "HomeAddress2", "mozillaHomeStreet2", DEF_CARD_ACCESS( HomeAddress2
) },
91 { "HomeCity", "homelocality,mozillaHomeLocalityName", DEF_CARD_ACCESS( HomeCity
) },
92 { "HomeState", "homeregion,mozillaHomeState", DEF_CARD_ACCESS( HomeState
) },
93 { "HomeZipCode", "homepostalcode,mozillaHomePostalCode", DEF_CARD_ACCESS( HomeZipCode
) },
94 { "HomeCountry", "homecountryname,mozillaHomeCountryName", DEF_CARD_ACCESS( HomeCountry
) },
95 { "WorkAddress", "postofficebox,streetaddress,streetaddress1", DEF_CARD_ACCESS( WorkAddress
) },
96 { "WorkAddress2", "streetaddress2", DEF_CARD_ACCESS( WorkAddress2
) },
97 { "WorkCity", "l,locality", DEF_CARD_ACCESS( WorkCity
) },
98 { "WorkState", "st,region", DEF_CARD_ACCESS( WorkState
) },
99 { "WorkZipCode", "postalcode,zip", DEF_CARD_ACCESS( WorkZipCode
) },
100 { "WorkCountry", "countryname", DEF_CARD_ACCESS( WorkCountry
) },
101 { "JobTitle", "title", DEF_CARD_ACCESS( JobTitle
) },
102 { "Department", "ou,orgunit,department,departmentnumber", DEF_CARD_ACCESS( Department
) },
103 { "Company", "o,company", DEF_CARD_ACCESS( Company
) },
104 { "WebPage1", "workurl", DEF_CARD_ACCESS( WebPage1
) },
105 { "WebPage2", "homeurl", DEF_CARD_ACCESS( WebPage2
) },
106 { "BirthYear", "birthyear", DEF_CARD_ACCESS( BirthYear
) },
107 { "BirthMonth", "birthmonth", DEF_CARD_ACCESS( BirthMonth
) },
108 { "BirthDay", "birthday", DEF_CARD_ACCESS( BirthDay
) },
109 { "Custom1", "custom1", DEF_CARD_ACCESS( Custom1
) },
110 { "Custom2", "custom2", DEF_CARD_ACCESS( Custom2
) },
111 { "Custom3", "custom3", DEF_CARD_ACCESS( Custom3
) },
112 { "Custom4", "custom4", DEF_CARD_ACCESS( Custom4
) },
113 { "Notes", "notes,description", DEF_CARD_ACCESS( Notes
) },
114 { "PreferMailFormat", "xmozillausehtmlmail", NULL
, NULL
},
115 { NULL
, NULL
, NULL
, NULL
}
117 const MapEntry
* loop
= aEntries
;
118 while ( loop
->pAsciiPropertyName
)
120 aMap
[ OString( loop
->pAsciiPropertyName
) ] =
121 CardPropertyData( loop
->pAsciiAttrributeList
, loop
->PropGetter
, loop
->PropSetter
);
130 struct AttributeMap_Data
134 MLdapAttributeMap::MLdapAttributeMap()
135 :m_pData( new AttributeMap_Data
)
140 MLdapAttributeMap::~MLdapAttributeMap()
145 NS_IMPL_THREADSAFE_ISUPPORTS1( MLdapAttributeMap
, nsIAbLDAPAttributeMap
)
148 NS_IMETHODIMP
MLdapAttributeMap::GetAttributeList(const nsACString
& aProperty
, nsACString
& _retval
)
150 OString
sProperty( MTypeConverter::nsACStringToOString( aProperty
) );
152 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
153 MapPropertiesToAttributes::const_iterator pos
= rPropertyMap
.find( sProperty
);
155 if ( pos
== rPropertyMap
.end() )
157 _retval
.SetIsVoid( PR_TRUE
);
161 MTypeConverter::asciiToNsACString( pos
->second
.pLDAPAttributeList
, _retval
);
168 NS_IMETHODIMP
MLdapAttributeMap::GetAttributes(const nsACString
& aProperty
, PRUint32
* aCount
, char*** aAttrs
)
170 OSL_FAIL( "MLdapAttributeMap::GetAttributes: not implemented!" );
174 return NS_ERROR_NOT_IMPLEMENTED
;
178 NS_IMETHODIMP
MLdapAttributeMap::GetFirstAttribute(const nsACString
& aProperty
, nsACString
& _retval
)
180 OString
sProperty( MTypeConverter::nsACStringToOString( aProperty
) );
182 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
183 MapPropertiesToAttributes::const_iterator pos
= rPropertyMap
.find( sProperty
);
185 if ( pos
== rPropertyMap
.end() )
187 _retval
.SetIsVoid( PR_TRUE
);
191 sal_Int32
tokenPos(0);
192 OString
sAttributeList( pos
->second
.pLDAPAttributeList
);
193 MTypeConverter::asciiToNsACString( sAttributeList
.getToken( 0, ',', tokenPos
).getStr(), _retval
);
200 NS_IMETHODIMP
MLdapAttributeMap::SetAttributeList(const nsACString
& aProperty
, const nsACString
& aAttributeList
, PRBool allowInconsistencies
)
202 OSL_FAIL( "MLdapAttributeMap::SetAttributeList: not implemented!" );
204 (void)aAttributeList
;
205 (void)allowInconsistencies
;
206 return NS_ERROR_NOT_IMPLEMENTED
;
210 NS_IMETHODIMP
MLdapAttributeMap::GetProperty(const nsACString
& aAttribute
, nsACString
& _retval
)
212 OSL_FAIL( "MLdapAttributeMap::GetProperty: not implemented!" );
215 return NS_ERROR_NOT_IMPLEMENTED
;
219 NS_IMETHODIMP
MLdapAttributeMap::GetAllCardAttributes(nsACString
& _retval
)
221 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
223 OStringBuffer aAllAttributes
;
224 for ( MapPropertiesToAttributes::const_iterator loop
= rPropertyMap
.begin();
225 loop
!= rPropertyMap
.end();
229 aAllAttributes
.append( loop
->second
.pLDAPAttributeList
);
230 if ( loop
!= rPropertyMap
.end() )
231 aAllAttributes
.append( ',' );
234 MTypeConverter::asciiToNsACString( aAllAttributes
.getStr(), _retval
);
239 NS_IMETHODIMP
MLdapAttributeMap::CheckState()
241 // we do not allow modifying the map, so we're always in a valid state
246 NS_IMETHODIMP
MLdapAttributeMap::SetFromPrefs(const nsACString
& aPrefBranchName
)
248 OSL_FAIL( "MLdapAttributeMap::SetFromPrefs: not implemented!" );
249 (void)aPrefBranchName
;
250 return NS_ERROR_NOT_IMPLEMENTED
;
254 NS_IMETHODIMP
MLdapAttributeMap::SetCardPropertiesFromLDAPMessage(nsILDAPMessage
* aMessage
, nsIAbCard
* aCard
)
256 NS_ENSURE_ARG_POINTER( aMessage
);
257 NS_ENSURE_ARG_POINTER( aCard
);
259 // in case that's not present in the LDAP message: set the "preferred mail format" to "none"
260 aCard
->SetPreferMailFormat( nsIAbPreferMailFormat::unknown
);
262 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
263 for ( MapPropertiesToAttributes::const_iterator prop
= rPropertyMap
.begin();
264 prop
!= rPropertyMap
.end();
268 // split the list of attributes for the current property
269 OString
sAttributeList( prop
->second
.pLDAPAttributeList
);
272 sal_Int32 tokenPos
= 0;
273 while ( tokenPos
!= -1 )
275 sAttribute
= sAttributeList
.getToken( 0, ',', tokenPos
);
277 // retrieve the values for the current attribute
278 PRUint32 valueCount
= 0;
279 PRUnichar
** values
= NULL
;
280 nsresult rv
= aMessage
->GetValues( sAttribute
.getStr(), &valueCount
, &values
);
281 if ( NS_FAILED( rv
) )
282 // try the next attribute
287 CardPropertySetter propSetter
= prop
->second
.PropSetter
;
288 OSL_ENSURE( propSetter
,
289 "MLdapAttributeMap::SetCardPropertiesFromLDAPMessage: "
290 "unexpected: could retrieve an attribute value, but have no setter for it!" );
293 (aCard
->*propSetter
)( values
[0] );
296 // we're done with this property - no need to handle the remaining attributes which
308 struct PreferMailFormatType
310 const sal_Char
* description
;
313 PreferMailFormatType()
315 ,formatType( nsIAbPreferMailFormat::unknown
)
319 PreferMailFormatType( const sal_Char
* _description
, PRUint32 _formatType
)
320 :description( _description
)
321 ,formatType( _formatType
)
326 static const PreferMailFormatType
* lcl_getMailFormatTypes()
328 static const PreferMailFormatType aMailFormatTypes
[] =
330 PreferMailFormatType( "text/plain", nsIAbPreferMailFormat::plaintext
),
331 PreferMailFormatType( "text/html", nsIAbPreferMailFormat::html
),
332 PreferMailFormatType( "unknown", nsIAbPreferMailFormat::unknown
),
333 PreferMailFormatType()
335 return aMailFormatTypes
;
340 void MLdapAttributeMap::fillCardFromResult( nsIAbCard
& _card
, const MQueryHelperResultEntry
& _result
)
342 _card
.SetPreferMailFormat( nsIAbPreferMailFormat::unknown
);
344 OUString resultValue
;
346 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
347 for ( MapPropertiesToAttributes::const_iterator prop
= rPropertyMap
.begin();
348 prop
!= rPropertyMap
.end();
352 resultValue
= _result
.getValue( prop
->first
);
354 CardPropertySetter propSetter
= prop
->second
.PropSetter
;
357 // PRUnichar != sal_Unicode in mingw
358 (_card
.*propSetter
)( reinterpret_cast_mingw_only
<const PRUnichar
*>(resultValue
.getStr()) );
362 if ( prop
->first
.equals( "PreferMailFormat" ) )
364 unsigned int format
= nsIAbPreferMailFormat::unknown
;
365 const PreferMailFormatType
* pMailFormatType
= lcl_getMailFormatTypes();
366 while ( pMailFormatType
->description
)
368 if ( resultValue
.equalsAscii( pMailFormatType
->description
) )
370 format
= pMailFormatType
->formatType
;
375 _card
.SetPreferMailFormat(format
);
378 OSL_FAIL( "MLdapAttributeMap::fillCardFromResult: unexpected property without default setters!" );
384 void MLdapAttributeMap::fillResultFromCard( MQueryHelperResultEntry
& _result
, nsIAbCard
& _card
)
387 OUString resultValue
;
389 const MapPropertiesToAttributes
& rPropertyMap( lcl_getPropertyMap() );
390 for ( MapPropertiesToAttributes::const_iterator prop
= rPropertyMap
.begin();
391 prop
!= rPropertyMap
.end();
395 CardPropertyGetter propGetter
= prop
->second
.PropGetter
;
398 (_card
.*propGetter
)( getter_Copies( value
) );
400 nsAutoString
temp( value
);
401 MTypeConverter::nsStringToOUString( temp
, resultValue
);
405 if ( prop
->first
.equals( "PreferMailFormat" ) )
407 unsigned int format
= nsIAbPreferMailFormat::unknown
;
408 _card
.GetPreferMailFormat( &format
);
409 const PreferMailFormatType
* pMailFormatType
= lcl_getMailFormatTypes();
410 while ( pMailFormatType
->description
)
412 if ( format
== pMailFormatType
->formatType
)
414 resultValue
= OUString::createFromAscii( pMailFormatType
->description
);
421 OSL_FAIL( "MLdapAttributeMap::fillResultFromCard: unexpected property without default getters!" );
424 _result
.insert( prop
->first
, resultValue
);
429 } } // namespace connectivity::mozab
432 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */