/* SOGoContactLDAPFolder.m - this file is part of SOGo * * Copyright (C) 2006 Inverse groupe conseil * * Author: Wolfgang Sourdeau * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #import #import #import #import #import #import #import #import #import #import #import #import #import #import #import "SOGoContactLDIFEntry.h" #import "SOGoContactLDAPFolder.h" #import #import #import @class WOContext; @implementation SOGoContactLDAPFolder #warning this should be unified within SOGoFolder - (void) appendObject: (NSDictionary *) object withBaseURL: (NSString *) baseURL toREPORTResponse: (WOResponse *) r { SOGoContactLDIFEntry *component; NSString *name, *etagLine, *contactString; name = [object objectForKey: @"c_name"]; component = [self lookupName: name inContext: context acquire: NO]; [r appendContentString: @" \r\n"]; [r appendContentString: @" "]; [r appendContentString: baseURL]; if (![baseURL hasSuffix: @"/"]) [r appendContentString: @"/"]; [r appendContentString: name]; [r appendContentString: @"\r\n"]; [r appendContentString: @" \r\n"]; [r appendContentString: @" \r\n"]; etagLine = [NSString stringWithFormat: @" %@\r\n", [component davEntityTag]]; [r appendContentString: etagLine]; [r appendContentString: @" \r\n"]; [r appendContentString: @" HTTP/1.1 200 OK\r\n"]; [r appendContentString: @" \r\n"]; [r appendContentString: @" "]; contactString = [[component contentAsString] stringByEscapingXMLString]; [r appendContentString: contactString]; [r appendContentString: @"\r\n"]; [r appendContentString: @" \r\n"]; } + (id) folderWithName: (NSString *) aName andDisplayName: (NSString *) aDisplayName inContainer: (id) aContainer { id folder; folder = [[self alloc] initWithName: aName andDisplayName: aDisplayName inContainer: aContainer]; [folder autorelease]; return folder; } - (id) init { if ((self = [super init])) { entries = nil; ldapSource = nil; } return self; } - (id) initWithName: (NSString *) newName andDisplayName: (NSString *) newDisplayName inContainer: (id) newContainer { if ((self = [self initWithName: newName inContainer: newContainer])) { ASSIGN (displayName, newDisplayName); } return self; } - (void) dealloc { [entries release]; [ldapSource release]; [super dealloc]; } - (void) setLDAPSource: (LDAPSource *) newLDAPSource { ASSIGN (ldapSource, newLDAPSource); } - (NSArray *) davNamespaces { return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"]; } - (NSString *) groupDavResourceType { return @"vcard-collection"; } - (id) lookupName: (NSString *) objectName inContext: (WOContext *) lookupContext acquire: (BOOL) acquire { id obj; NSDictionary *ldifEntry; //NSLog (@"looking up name '%@'...", objectName); /* first check attributes directly bound to the application */ obj = [super lookupName: objectName inContext: lookupContext acquire: NO]; if (!obj) { ldifEntry = [ldapSource lookupContactEntry: objectName]; obj = ((ldifEntry) ? [SOGoContactLDIFEntry contactEntryWithName: objectName withLDIFEntry: ldifEntry inContainer: self] : [NSException exceptionWithHTTPStatus: 404]); } return obj; } - (NSArray *) toOneRelationshipKeys { return [ldapSource allEntryIDs]; } - (NSArray *) _flattenedRecords: (NSArray *) records { NSMutableArray *newRecords; NSEnumerator *oldRecords; NSDictionary *oldRecord; NSMutableDictionary *newRecord; NSString *data; newRecords = [[NSMutableArray alloc] initWithCapacity: [records count]]; [newRecords autorelease]; oldRecords = [records objectEnumerator]; oldRecord = [oldRecords nextObject]; while (oldRecord) { newRecord = [NSMutableDictionary new]; [newRecord autorelease]; [newRecord setObject: [oldRecord objectForKey: @"c_uid"] forKey: @"c_uid"]; [newRecord setObject: [oldRecord objectForKey: @"c_name"] forKey: @"c_name"]; data = [oldRecord objectForKey: @"displayName"]; if (!data) data = [oldRecord objectForKey: @"c_cn"]; if (!data) data = @""; [newRecord setObject: data forKey: @"displayName"]; data = [oldRecord objectForKey: @"mail"]; if (!data) data = @""; [newRecord setObject: data forKey: @"mail"]; data = [oldRecord objectForKey: @"nsAIMid"]; if (![data length]) data = [oldRecord objectForKey: @"nscpaimscreenname"]; if (![data length]) data = @""; [newRecord setObject: data forKey: @"screenName"]; data = [oldRecord objectForKey: @"o"]; if (!data) data = @""; [newRecord setObject: data forKey: @"org"]; data = [oldRecord objectForKey: @"telephoneNumber"]; if (![data length]) data = [oldRecord objectForKey: @"cellphone"]; if (![data length]) data = [oldRecord objectForKey: @"homePhone"]; if (![data length]) data = @""; [newRecord setObject: data forKey: @"phone"]; [newRecords addObject: newRecord]; oldRecord = [oldRecords nextObject]; } return newRecords; } - (NSArray *) lookupContactsWithFilter: (NSString *) filter sortBy: (NSString *) sortKey ordering: (NSComparisonResult) sortOrdering { NSArray *records, *result; EOSortOrdering *ordering; result = nil; if (filter && [filter length] > 0) { records = [self _flattenedRecords: [ldapSource fetchContactsMatching: filter]]; ordering = [EOSortOrdering sortOrderingWithKey: sortKey selector: ((sortOrdering == NSOrderedDescending) ? EOCompareCaseInsensitiveDescending : EOCompareCaseInsensitiveAscending)]; result = [records sortedArrayUsingKeyOrderArray: [NSArray arrayWithObject: ordering]]; } return result; } - (NSString *) davDisplayName { return displayName; } - (BOOL) isFolderish { return YES; } /* folder type */ - (NSString *) folderType { return @"Contact"; } - (NSString *) outlookFolderClass { return @"IPF.Contact"; } /* sorting */ - (NSComparisonResult) compare: (id) otherFolder { NSComparisonResult comparison; if ([NSStringFromClass([otherFolder class]) isEqualToString: @"SOGoContactGCSFolder"]) comparison = NSOrderedDescending; else comparison = [[self displayName] localizedCaseInsensitiveCompare: [otherFolder displayName]]; return comparison; } /* acls */ - (NSString *) ownerInContext: (WOContext *) noContext { return @"nobody"; } /* TODO: this might change one day when we support LDAP acls */ - (NSArray *) aclsForUser: (NSString *) uid { return nil; } @end