]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Contacts/SOGoContactGCSFolder.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1126 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / Contacts / SOGoContactGCSFolder.m
1 /*
2   Copyright (C) 2004-2005 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #import <Foundation/NSArray.h>
23 #import <Foundation/NSString.h>
24 #import <NGObjWeb/NSException+HTTP.h>
25 #import <NGObjWeb/SoObject+SoDAV.h>
26 #import <NGObjWeb/WOContext.h>
27 #import <NGObjWeb/WORequest.h>
28 #import <NGExtensions/NSObject+Logs.h>
29 #import <EOControl/EOQualifier.h>
30 #import <EOControl/EOSortOrdering.h>
31 #import <GDLContentStore/GCSFolder.h>
32
33 #import "SOGoContactGCSEntry.h"
34 #import "SOGoContactGCSFolder.h"
35
36 #define folderListingFields [NSArray arrayWithObjects: @"c_name", @"c_cn", \
37                                      @"c_givenname", @"c_screenname", \
38                                      @"c_o", @"c_mail", @"c_telephonenumber", \
39                                      nil]
40
41 @implementation SOGoContactGCSFolder
42
43 + (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
44                                   andDisplayName: (NSString *) aDisplayName
45                                      inContainer: (SOGoObject *) aContainer
46 {
47   SOGoContactGCSFolder *folder;
48
49   folder = [[self alloc] initWithName: aName
50                          andDisplayName: aDisplayName
51                          inContainer: aContainer];
52   [folder autorelease];
53
54   return folder;
55 }
56
57 - (void) dealloc
58 {
59   [displayName release];
60   [super dealloc];
61 }
62
63 - (id <SOGoContactFolder>) initWithName: (NSString *) newName
64                          andDisplayName: (NSString *) newDisplayName
65                             inContainer: (SOGoObject *) newContainer
66 {
67   if ((self = [self initWithName: newName
68                     inContainer: newContainer]))
69     ASSIGN (displayName, newDisplayName);
70
71   return self;
72 }
73
74 - (BOOL) folderIsMandatory
75 {
76   return [nameInContainer isEqualToString: @"personal"];
77 }
78
79 - (NSString *) displayName
80 {
81   return displayName;
82 }
83
84 /* name lookup */
85
86 - (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
87 {
88   SOGoContactGCSEntry *contact;
89
90   if ([recordId length] > 0)
91     contact = [SOGoContactGCSEntry objectWithName: recordId
92                                    inContainer: self];
93   else
94     contact = nil;
95
96   return contact;
97 }
98
99 - (id) lookupName: (NSString *) _key
100         inContext: (WOContext *) _ctx
101           acquire: (BOOL) _flag
102 {
103   id obj;
104   BOOL isPut;
105
106   isPut = NO;
107   /* first check attributes directly bound to the application */
108   obj = [super lookupName:_key inContext:_ctx acquire:NO];
109   if (!obj)
110     {
111       if ([[[_ctx request] method] isEqualToString: @"PUT"])
112         {
113           if ([_key isEqualToString: @"PUT"])
114             isPut = YES;
115           else
116             obj = [SOGoContactGCSEntry objectWithName: _key
117                                        inContainer: self];
118         }
119       else
120         obj = [self lookupContactWithId: _key];
121     }
122 //   if (!(obj || isPut))
123 //     obj = [NSException exceptionWithHTTPStatus:404 /* Not Found */];
124
125 // #if 0
126 //     if ([[self ocsFolder] versionOfContentWithName:_key])
127 // #endif
128 //       return [self contactWithName:_key inContext:_ctx];
129 //   }
130
131   /* return 404 to stop acquisition */
132   return obj;
133 }
134
135 /* fetching */
136 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
137 {
138   NSString *qs;
139   EOQualifier *qualifier;
140
141   if (filter && [filter length] > 0)
142     {
143       qs = [NSString stringWithFormat:
144                        @"(c_sn isCaseInsensitiveLike: '%@%%') OR "
145                      @"(c_givenname isCaseInsensitiveLike: '%@%%') OR "
146                      @"(c_mail isCaseInsensitiveLike: '%@%%') OR "
147                      @"(c_telephonenumber isCaseInsensitiveLike: '%%%@%%')",
148                      filter, filter, filter, filter];
149       qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
150     }
151   else
152     qualifier = nil;
153
154   return qualifier;
155 }
156
157 - (NSArray *) _flattenedRecords: (NSArray *) records
158 {
159   NSMutableArray *newRecords;
160   NSEnumerator *oldRecords;
161   NSDictionary *oldRecord;
162   NSMutableDictionary *newRecord;
163   NSString *data;
164   
165   newRecords = [NSMutableArray arrayWithCapacity: [records count]];
166
167   oldRecords = [records objectEnumerator];
168   oldRecord = [oldRecords nextObject];
169   while (oldRecord)
170     {
171       newRecord = [NSMutableDictionary new];
172       [newRecord autorelease];
173
174       [newRecord setObject: [oldRecord objectForKey: @"c_name"]
175                  forKey: @"c_uid"];
176       [newRecord setObject: [oldRecord objectForKey: @"c_name"]
177                  forKey: @"c_name"];
178
179       data = [oldRecord objectForKey: @"c_cn"];
180       if (!data)
181         data = @"";
182       [newRecord setObject: data
183                  forKey: @"displayName"];
184
185       data = [oldRecord objectForKey: @"c_mail"];
186       if (!data)
187         data = @"";
188       [newRecord setObject: data forKey: @"mail"];
189
190       data = [oldRecord objectForKey: @"c_screenname"];
191       if (!data)
192         data = @"";
193       [newRecord setObject: data forKey: @"screenName"];
194
195       data = [oldRecord objectForKey: @"c_o"];
196       if (!data)
197         data = @"";
198       [newRecord setObject: data forKey: @"org"];
199
200       data = [oldRecord objectForKey: @"c_telephonenumber"];
201       if (![data length])
202         data = @"";
203       [newRecord setObject: data forKey: @"phone"];
204
205       [newRecords addObject: newRecord];
206       oldRecord = [oldRecords nextObject];
207     }
208
209   return newRecords;
210 }
211
212 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
213                                 sortBy: (NSString *) sortKey
214                               ordering: (NSComparisonResult) sortOrdering
215 {
216   NSArray *fields, *dbRecords, *records;
217   EOQualifier *qualifier;
218   EOSortOrdering *ordering;
219
220 //   NSLog (@"fetching records matching '%@', sorted by '%@' in order %d",
221 //          filter, sortKey, sortOrdering);
222
223   fields = folderListingFields;
224   qualifier = [self _qualifierForFilter: filter];
225   dbRecords = [[self ocsFolder] fetchFields: fields
226                                 matchingQualifier: qualifier];
227   if ([dbRecords count] > 0)
228     {
229       records = [self _flattenedRecords: dbRecords];
230       ordering
231         = [EOSortOrdering sortOrderingWithKey: sortKey
232                           selector: ((sortOrdering == NSOrderedDescending)
233                                      ? EOCompareCaseInsensitiveDescending
234                                      : EOCompareCaseInsensitiveAscending)];
235       records
236         = [records sortedArrayUsingKeyOrderArray:
237                      [NSArray arrayWithObject: ordering]];
238     }
239   else
240     records = nil;
241 //   else
242 //     [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
243
244   //[self debugWithFormat:@"fetched %i records.", [records count]];
245   return records;
246 }
247
248 - (NSArray *) davNamespaces
249 {
250   return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"];
251 }
252
253 - (NSArray *) davComplianceClassesInContext: (id)_ctx
254 {
255   NSMutableArray *classes;
256   NSArray *primaryClasses;
257
258   classes = [NSMutableArray new];
259   [classes autorelease];
260
261   primaryClasses = [super davComplianceClassesInContext: _ctx];
262   if (primaryClasses)
263     [classes addObjectsFromArray: primaryClasses];
264   [classes addObject: @"access-control"];
265   [classes addObject: @"addressbook-access"];
266
267   return classes;
268 }
269
270 - (NSString *) groupDavResourceType
271 {
272   return @"vcard-collection";
273 }
274
275 - (NSException *) delete
276 {
277   return (([nameInContainer isEqualToString: @"personal"])
278           ? [NSException exceptionWithHTTPStatus: 403
279                          reason: @"the 'personal' folder cannot be deleted"]
280           : [super delete]);
281 }
282
283 // /* GET */
284
285 // - (id) GETAction: (id)_ctx
286 // {
287 //   // TODO: I guess this should really be done by SOPE (redirect to
288 //   //       default method)
289 //   WOResponse *r;
290 //   NSString *uri;
291
292 //   uri = [[_ctx request] uri];
293 //   if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
294 //   uri = [uri stringByAppendingString:@"view"];
295   
296 //   r = [_ctx response];
297 //   [r setStatus:302 /* moved */];
298 //   [r setHeader:uri forKey:@"location"];
299 //   return r;
300 // }
301
302 /* folder type */
303
304 - (NSString *) folderType
305 {
306   return @"Contact";
307 }
308
309 - (NSString *) outlookFolderClass
310 {
311   return @"IPF.Contact";
312 }
313
314 @end /* SOGoContactGCSFolder */