2 Copyright (C) 2004-2005 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #import <Foundation/NSArray.h>
23 #import <Foundation/NSString.h>
25 #import <NGObjWeb/NSException+HTTP.h>
26 #import <NGObjWeb/SoObject+SoDAV.h>
27 #import <NGObjWeb/WOContext.h>
28 #import <NGObjWeb/WORequest.h>
29 #import <NGExtensions/NSObject+Logs.h>
30 #import <EOControl/EOQualifier.h>
31 #import <EOControl/EOSortOrdering.h>
32 #import <GDLContentStore/GCSFolder.h>
34 #import <SoObjects/SOGo/NSDictionary+Utilities.h>
35 #import "SOGoContactGCSEntry.h"
36 #import "SOGoContactGCSFolder.h"
38 #define folderListingFields [NSArray arrayWithObjects: @"c_name", @"c_cn", \
39 @"c_givenname", @"c_sn", @"c_screenname", \
40 @"c_o", @"c_mail", @"c_telephonenumber", \
43 @implementation SOGoContactGCSFolder
47 - (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
49 SOGoContactGCSEntry *contact;
51 if ([recordId length] > 0)
52 contact = [SOGoContactGCSEntry objectWithName: recordId
60 - (id) lookupName: (NSString *) _key
61 inContext: (WOContext *) _ctx
68 obj = [super lookupName:_key inContext:_ctx acquire:NO];
71 if ([[[_ctx request] method] isEqualToString: @"PUT"])
73 if ([_key isEqualToString: @"PUT"])
76 obj = [SOGoContactGCSEntry objectWithName: _key
80 obj = [self lookupContactWithId: _key];
82 // if (!(obj || isPut))
83 // obj = [NSException exceptionWithHTTPStatus:404 /* Not Found */];
86 // if ([[self ocsFolder] versionOfContentWithName:_key])
88 // return [self contactWithName:_key inContext:_ctx];
91 /* return 404 to stop acquisition */
96 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
99 EOQualifier *qualifier;
101 if (filter && [filter length] > 0)
103 qs = [NSString stringWithFormat:
104 @"(c_sn isCaseInsensitiveLike: '%@%%') OR "
105 @"(c_givenname isCaseInsensitiveLike: '%@%%') OR "
106 @"(c_mail isCaseInsensitiveLike: '%@%%') OR "
107 @"(c_telephonenumber isCaseInsensitiveLike: '%%%@%%')",
108 filter, filter, filter, filter];
109 qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
117 - (NSArray *) _flattenedRecords: (NSArray *) records
119 NSMutableArray *newRecords;
120 NSEnumerator *oldRecords;
121 NSDictionary *oldRecord;
122 NSMutableDictionary *newRecord;
125 newRecords = [NSMutableArray arrayWithCapacity: [records count]];
127 oldRecords = [records objectEnumerator];
128 oldRecord = [oldRecords nextObject];
131 newRecord = [NSMutableDictionary new];
132 [newRecord autorelease];
134 [newRecord setObject: [oldRecord objectForKey: @"c_name"]
136 [newRecord setObject: [oldRecord objectForKey: @"c_name"]
139 data = [oldRecord objectForKey: @"c_cn"];
141 data = [oldRecord keysWithFormat: @"%{c_givenname} %{c_sn}"];
142 [newRecord setObject: data
143 forKey: @"displayName"];
145 data = [oldRecord objectForKey: @"c_mail"];
148 [newRecord setObject: data forKey: @"mail"];
150 data = [oldRecord objectForKey: @"c_screenname"];
153 [newRecord setObject: data forKey: @"screenName"];
155 data = [oldRecord objectForKey: @"c_o"];
158 [newRecord setObject: data forKey: @"org"];
160 data = [oldRecord objectForKey: @"c_telephonenumber"];
163 [newRecord setObject: data forKey: @"phone"];
165 [newRecords addObject: newRecord];
166 oldRecord = [oldRecords nextObject];
172 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
173 sortBy: (NSString *) sortKey
174 ordering: (NSComparisonResult) sortOrdering
176 NSArray *fields, *dbRecords, *records;
177 EOQualifier *qualifier;
178 EOSortOrdering *ordering;
180 // NSLog (@"fetching records matching '%@', sorted by '%@' in order %d",
181 // filter, sortKey, sortOrdering);
183 fields = folderListingFields;
184 qualifier = [self _qualifierForFilter: filter];
185 dbRecords = [[self ocsFolder] fetchFields: fields
186 matchingQualifier: qualifier];
187 if ([dbRecords count] > 0)
189 records = [self _flattenedRecords: dbRecords];
191 = [EOSortOrdering sortOrderingWithKey: sortKey
192 selector: ((sortOrdering == NSOrderedDescending)
193 ? EOCompareCaseInsensitiveDescending
194 : EOCompareCaseInsensitiveAscending)];
196 = [records sortedArrayUsingKeyOrderArray:
197 [NSArray arrayWithObject: ordering]];
202 // [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
204 //[self debugWithFormat:@"fetched %i records.", [records count]];
208 - (NSArray *) davNamespaces
210 return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"];
213 - (NSArray *) davComplianceClassesInContext: (id)_ctx
215 NSMutableArray *classes;
216 NSArray *primaryClasses;
218 classes = [NSMutableArray new];
219 [classes autorelease];
221 primaryClasses = [super davComplianceClassesInContext: _ctx];
223 [classes addObjectsFromArray: primaryClasses];
224 [classes addObject: @"access-control"];
225 [classes addObject: @"addressbook-access"];
230 - (NSString *) groupDavResourceType
232 return @"vcard-collection";
237 // - (id) GETAction: (id)_ctx
239 // // TODO: I guess this should really be done by SOPE (redirect to
240 // // default method)
244 // uri = [[_ctx request] uri];
245 // if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
246 // uri = [uri stringByAppendingString:@"view"];
248 // r = [_ctx response];
249 // [r setStatus:302 /* moved */];
250 // [r setHeader:uri forKey:@"location"];
256 - (NSString *) folderType
261 - (NSString *) outlookFolderClass
263 return @"IPF.Contact";
266 @end /* SOGoContactGCSFolder */