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", \
49 @"sn", @"givenname", @"l", \
50 @"mail", @"telephonenumber", \
57 @implementation SOGoContactLDAPFolder
59 + (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
60 andDisplayName: (NSString *) aDisplayName
61 inContainer: (SOGoObject *) aContainer
63 SOGoContactLDAPFolder *folder;
65 folder = [[self alloc] initWithName: aName
66 andDisplayName: aDisplayName
67 inContainer: aContainer];
75 if ((self = [super init]))
78 contactIdentifier = nil;
87 - (id <SOGoContactFolder>) initWithName: (NSString *) aName
88 andDisplayName: (NSString *) aDisplayName
89 inContainer: (SOGoObject *) aContainer
91 if ((self = [self initWithName: aName
92 inContainer: aContainer]))
93 [self setDisplayName: aDisplayName];
102 if ([connection isBound])
104 [connection release];
106 if (contactIdentifier)
107 [contactIdentifier release];
109 [userIdentifier release];
117 - (void) setDisplayName: (NSString *) aDisplayName
120 [displayName release];
121 displayName = aDisplayName;
123 [displayName retain];
126 - (NSString *) displayName
131 - (void) LDAPSetHostname: (NSString *) aHostname
133 setBindDN: (NSString *) aBindDN
134 setBindPW: (NSString *) aBindPW
135 setContactIdentifier: (NSString *) aCI
136 setUserIdentifier: (NSString *) aUI
137 setRootDN: (NSString *) aRootDN;
139 connection = [[NGLdapConnection alloc] initWithHostName: aHostname
141 [connection bindWithMethod: nil
143 credentials: aBindPW];
147 rootDN = [aRootDN copy];
148 if (contactIdentifier)
149 [contactIdentifier release];
150 contactIdentifier = [aCI copy];
152 [userIdentifier release];
153 userIdentifier = [aUI copy];
156 - (NGLdapConnection *) LDAPconnection
161 - (NGLdapAttribute *) _attrWithName: (NSString *) aName
163 return [[[NGLdapAttribute alloc] initWithAttributeName: aName] autorelease];
166 - (NSArray *) _searchAttributes
168 return [NSArray arrayWithObjects:
183 @"mozillaHomeCountryName",
200 @"facsimileTelephoneNumber",
202 @"mozillaHomeStreet",
203 @"mozillaSecondEmail",
204 @"xmozillasecondemail",
208 @"nscpaimscreenname",
216 @"mozillaHomePostalCode",
217 @"mozillaHomeLocalityName",
218 @"mozillaWorkStreet2",
219 @"mozillaUseHtmlMail",
220 @"xmozillausehtmlmail",
221 @"mozillaHomeStreet2",
241 - (void) _loadEntries: (NSString *) entryId
243 NSEnumerator *contacts;
248 entries = [NSMutableDictionary new];
252 if (![entries objectForKey: entryId])
255 = [connection entryAtDN:
256 [NSString stringWithFormat: @"%@=%@,%@",
257 contactIdentifier, entryId, rootDN]
258 attributes: [self _searchAttributes]];
260 [entries setObject: entry forKey: entryId];
265 contacts = [connection deepSearchAtBaseDN: rootDN
267 attributes: [self _searchAttributes]];
270 entry = [contacts nextObject];
273 key = [[entry attributeWithName: contactIdentifier]
274 stringValueAtIndex: 0];
275 if (key && ![entries objectForKey: key])
276 [entries setObject: entry forKey: key];
277 entry = [contacts nextObject];
283 - (id) lookupName: (NSString *) name
284 inContext: (WOContext *) lookupContext
285 acquire: (BOOL) acquire
290 // NSLog (@"looking up name '%@'...", name);
292 /* first check attributes directly bound to the application */
293 obj = [super lookupName: name inContext: lookupContext acquire: NO];
296 [self _loadEntries: name];
297 entry = [entries objectForKey: name];
299 ? [SOGoContactLDAPEntry contactEntryWithName: name
302 : [NSException exceptionWithHTTPStatus: 404]);
308 - (NSArray *) toOneRelationshipKeys
310 [self _loadEntries: nil];
312 return [entries allKeys];
315 - (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
319 [self _loadEntries: recordId];
321 entry = [entries objectForKey: recordId];
323 ? [SOGoContactLDAPEntry contactEntryWithName: recordId
329 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
332 EOQualifier *qualifier;
334 if (filter && [filter length] > 0)
336 qs = [NSString stringWithFormat:
339 @"OR (displayName='%@*')"
341 @"OR (telephoneNumber='*%@*')",
342 filter, filter, filter, filter, filter];
343 qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
351 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
352 sortBy: (NSString *) sortKey
353 ordering: (NSComparisonResult) sortOrdering
355 NSMutableArray *records;
358 NSEnumerator *contacts;
359 EOSortOrdering *ordering;
363 if (filter && [filter length] > 0)
365 // NSLog (@"%@: fetching records matching '*%@*', sorted by '%@'"
367 // self, filter, sortKey, sortOrdering);
369 records = [NSMutableArray new];
370 [records autorelease];
372 contacts = [connection deepSearchAtBaseDN: rootDN
373 qualifier: [self _qualifierForFilter: filter]
374 attributes: folderListingFields];
375 entry = [contacts nextObject];
378 [records addObject: [entry asDictionaryWithAttributeNames: nil
379 withUID: userIdentifier
380 andCName: contactIdentifier]];
381 entry = [contacts nextObject];
385 = [EOSortOrdering sortOrderingWithKey: sortKey
386 selector: ((sortOrdering == NSOrderedDescending)
387 ? EOCompareCaseInsensitiveDescending
388 : EOCompareCaseInsensitiveAscending)];
390 = [records sortedArrayUsingKeyOrderArray:
391 [NSArray arrayWithObject: ordering]];
394 //[self debugWithFormat:@"fetched %i records.", [records count]];
398 - (NSString *) groupDavResourceType
400 return @"vcard-collection";