1 /* SOGoContactLDAPFolder.m - this file is part of SOGo
3 * Copyright (C) 2006 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSString.h>
26 #import <Foundation/NSDictionary.h>
27 #import <Foundation/NSString.h>
29 #import <NGObjWeb/WOApplication.h>
30 #import <NGObjWeb/WOContext.h>
31 #import <NGObjWeb/WOContext+SoObjects.h>
32 #import <NGObjWeb/SoUser.h>
34 #import <NGLdap/NGLdapAttribute.h>
35 #import <NGLdap/NGLdapConnection.h>
36 #import <NGLdap/NGLdapEntry.h>
40 #import "NGLdapEntry+Contact.h"
42 #import "SOGoContactLDAPEntry.h"
43 #import "SOGoContactLDAPFolder.h"
45 #define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
48 @"sn", @"givenname", @"l", \
49 @"mail", @"telephonenumber", \
56 @implementation SOGoContactLDAPFolder
58 + (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
59 andDisplayName: (NSString *) aDisplayName
60 inContainer: (SOGoObject *) aContainer
62 SOGoContactLDAPFolder *folder;
64 folder = [[self alloc] initWithName: aName
65 andDisplayName: aDisplayName
66 inContainer: aContainer];
74 if ((self = [super init]))
77 contactIdentifier = nil;
86 - (id <SOGoContactFolder>) initWithName: (NSString *) aName
87 andDisplayName: (NSString *) aDisplayName
88 inContainer: (SOGoObject *) aContainer
90 if ((self = [self initWithName: aName
91 inContainer: aContainer]))
92 [self setDisplayName: aDisplayName];
101 if ([connection isBound])
103 [connection release];
105 if (contactIdentifier)
106 [contactIdentifier release];
108 [userIdentifier release];
116 - (void) setDisplayName: (NSString *) aDisplayName
119 [displayName release];
120 displayName = aDisplayName;
122 [displayName retain];
125 - (NSString *) displayName
130 - (void) LDAPSetHostname: (NSString *) aHostname
132 setBindDN: (NSString *) aBindDN
133 setBindPW: (NSString *) aBindPW
134 setContactIdentifier: (NSString *) aCI
135 setUserIdentifier: (NSString *) aUI
136 setRootDN: (NSString *) aRootDN;
138 connection = [[NGLdapConnection alloc] initWithHostName: aHostname
140 [connection bindWithMethod: nil
142 credentials: aBindPW];
146 rootDN = [aRootDN copy];
147 if (contactIdentifier)
148 [contactIdentifier release];
149 contactIdentifier = [aCI copy];
151 [userIdentifier release];
152 userIdentifier = [aUI copy];
155 - (NGLdapConnection *) LDAPconnection
160 - (NGLdapAttribute *) _attrWithName: (NSString *) aName
162 return [[[NGLdapAttribute alloc] initWithAttributeName: aName] autorelease];
165 - (NSArray *) _searchAttributes
167 return [NSArray arrayWithObjects:
182 @"mozillaHomeCountryName",
199 @"facsimileTelephoneNumber",
201 @"mozillaHomeStreet",
202 @"mozillaSecondEmail",
203 @"xmozillasecondemail",
207 @"nscpaimscreenname",
215 @"mozillaHomePostalCode",
216 @"mozillaHomeLocalityName",
217 @"mozillaWorkStreet2",
218 @"mozillaUseHtmlMail",
219 @"xmozillausehtmlmail",
220 @"mozillaHomeStreet2",
240 - (void) _loadEntries: (NSString *) entryId
242 NSEnumerator *contacts;
247 entries = [NSMutableDictionary new];
251 if (![entries objectForKey: entryId])
254 = [connection entryAtDN:
255 [NSString stringWithFormat: @"%@=%@,%@",
256 contactIdentifier, entryId, rootDN]
257 attributes: [self _searchAttributes]];
259 [entries setObject: entry forKey: entryId];
264 contacts = [connection deepSearchAtBaseDN: rootDN
266 attributes: [self _searchAttributes]];
269 entry = [contacts nextObject];
272 key = [[entry attributeWithName: contactIdentifier]
273 stringValueAtIndex: 0];
274 if (key && ![entries objectForKey: key])
275 [entries setObject: entry forKey: key];
276 entry = [contacts nextObject];
282 - (id) lookupName: (NSString *) name
283 inContext: (WOContext *) context
284 acquire: (BOOL) acquire
289 // NSLog (@"looking up name '%@'...", name);
291 /* first check attributes directly bound to the application */
292 obj = [super lookupName: name inContext: context acquire: NO];
295 [self _loadEntries: name];
296 entry = [entries objectForKey: name];
298 ? [SOGoContactLDAPEntry contactEntryWithName: name
301 : [NSException exceptionWithHTTPStatus: 404]);
307 - (NSArray *) toOneRelationshipKeys
309 [self _loadEntries: nil];
311 return [entries allKeys];
314 - (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
318 [self _loadEntries: recordId];
320 entry = [entries objectForKey: recordId];
322 ? [SOGoContactLDAPEntry contactEntryWithName: recordId
328 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
331 EOQualifier *qualifier;
333 if (filter && [filter length] > 0)
335 qs = [NSString stringWithFormat:
338 @"OR (displayName='%@*')"
340 @"OR (telephoneNumber='*%@*')",
341 filter, filter, filter, filter, filter];
342 qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
350 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
351 sortBy: (NSString *) sortKey
352 ordering: (NSComparisonResult) sortOrdering
354 NSMutableArray *records;
357 NSEnumerator *contacts;
358 EOSortOrdering *ordering;
362 if (filter && [filter length] > 0)
364 // NSLog (@"%@: fetching records matching '*%@*', sorted by '%@'"
366 // self, filter, sortKey, sortOrdering);
368 records = [NSMutableArray new];
369 [records autorelease];
371 contacts = [connection deepSearchAtBaseDN: rootDN
372 qualifier: [self _qualifierForFilter: filter]
373 attributes: folderListingFields];
374 entry = [contacts nextObject];
377 [records addObject: [entry asDictionaryWithAttributeNames: nil
378 withUID: userIdentifier
379 andCName: contactIdentifier]];
380 entry = [contacts nextObject];
384 = [EOSortOrdering sortOrderingWithKey: sortKey
385 selector: ((sortOrdering == NSOrderedDescending)
386 ? EOCompareCaseInsensitiveDescending
387 : EOCompareCaseInsensitiveAscending)];
389 = [records sortedArrayUsingKeyOrderArray:
390 [NSArray arrayWithObject: ordering]];
393 //[self debugWithFormat:@"fetched %i records.", [records count]];
397 - (NSString *) groupDavResourceType
399 return @"vcard-collection";