#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
+
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
#import <NGExtensions/NSObject+Logs.h>
+#import <NGExtensions/NSString+misc.h>
#import <EOControl/EOQualifier.h>
#import <EOControl/EOSortOrdering.h>
#import <GDLContentStore/GCSFolder.h>
+#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import "SOGoContactGCSEntry.h"
#import "SOGoContactGCSFolder.h"
#define folderListingFields [NSArray arrayWithObjects: @"c_name", @"c_cn", \
- @"c_givenname", @"c_screenname", \
+ @"c_givenname", @"c_sn", @"c_screenname", \
@"c_o", @"c_mail", @"c_telephonenumber", \
nil]
@implementation SOGoContactGCSFolder
-+ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
- andDisplayName: (NSString *) aDisplayName
- inContainer: (SOGoObject *) aContainer
-{
- SOGoContactGCSFolder *folder;
-
- folder = [[self alloc] initWithName: aName
- andDisplayName: aDisplayName
- inContainer: aContainer];
- [folder autorelease];
-
- return folder;
-}
-
-- (void) dealloc
-{
- [displayName release];
- [super dealloc];
-}
-
-- (id <SOGoContactFolder>) initWithName: (NSString *) newName
- andDisplayName: (NSString *) newDisplayName
- inContainer: (SOGoObject *) newContainer
-{
- if ((self = [self initWithName: newName
- inContainer: newContainer]))
- ASSIGN (displayName, newDisplayName);
-
- return self;
-}
-
-- (BOOL) folderIsMandatory
-{
- return [nameInContainer isEqualToString: @"personal"];
-}
-
-- (NSString *) displayName
-{
- return displayName;
-}
-
/* name lookup */
- (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
BOOL isPut;
isPut = NO;
- /* first check attributes directly bound to the application */
obj = [super lookupName:_key inContext:_ctx acquire:NO];
+
if (!obj)
{
if ([[[_ctx request] method] isEqualToString: @"PUT"])
forKey: @"c_name"];
data = [oldRecord objectForKey: @"c_cn"];
- if (!data)
- data = @"";
+ if (![data length])
+ data = [oldRecord keysWithFormat: @"%{c_givenname} %{c_sn}"];
[newRecord setObject: data
forKey: @"displayName"];
EOQualifier *qualifier;
EOSortOrdering *ordering;
-// NSLog (@"fetching records matching '%@', sorted by '%@' in order %d",
-// filter, sortKey, sortOrdering);
-
fields = folderListingFields;
qualifier = [self _qualifierForFilter: filter];
dbRecords = [[self ocsFolder] fetchFields: fields
matchingQualifier: qualifier];
+
if ([dbRecords count] > 0)
{
records = [self _flattenedRecords: dbRecords];
}
else
records = nil;
-// else
-// [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
+ // else
+ //[self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
- //[self debugWithFormat:@"fetched %i records.", [records count]];
+ [self debugWithFormat:@"fetched %i records.", [records count]];
return records;
}
-- (NSArray *) davNamespaces
+- (void) appendObject: (NSDictionary *) object
+ withBaseURL: (NSString *) baseURL
+ toREPORTResponse: (WOResponse *) r
{
- return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"];
+ SOGoContactGCSEntry *component;
+ Class componentClass;
+ NSString *name, *etagLine, *contactString;
+
+ name = [object objectForKey: @"c_name"];
+ componentClass = [SOGoContactGCSEntry class];
+
+ component = [componentClass objectWithName: name inContainer: self];
+
+ [r appendContentString: @" <D:response>\r\n"];
+ [r appendContentString: @" <D:href>"];
+ [r appendContentString: baseURL];
+ if (![baseURL hasSuffix: @"/"])
+ [r appendContentString: @"/"];
+ [r appendContentString: name];
+ [r appendContentString: @"</D:href>\r\n"];
+
+ [r appendContentString: @" <D:propstat>\r\n"];
+ [r appendContentString: @" <D:prop>\r\n"];
+ etagLine = [NSString stringWithFormat: @" <D:getetag>%@</D:getetag>\r\n",
+ [component davEntityTag]];
+ [r appendContentString: etagLine];
+ [r appendContentString: @" </D:prop>\r\n"];
+ [r appendContentString: @" <D:status>HTTP/1.1 200 OK</D:status>\r\n"];
+ [r appendContentString: @" </D:propstat>\r\n"];
+ [r appendContentString: @" <C:addressbook-data>"];
+ contactString = [[component contentAsString] stringByEscapingXMLString];
+ [r appendContentString: contactString];
+ [r appendContentString: @"</C:addressbook-data>\r\n"];
+ [r appendContentString: @" </D:response>\r\n"];
}
- (NSArray *) davComplianceClassesInContext: (id)_ctx
return classes;
}
-- (NSString *) groupDavResourceType
+- (NSArray *) davNamespaces
{
- return @"vcard-collection";
+ return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"];
}
-- (NSException *) delete
+- (NSString *) groupDavResourceType
{
- return (([nameInContainer isEqualToString: @"personal"])
- ? [NSException exceptionWithHTTPStatus: 403
- reason: @"the 'personal' folder cannot be deleted"]
- : [super delete]);
+ return @"vcard-collection";
}
// /* GET */
// return r;
// }
+/* sorting */
+- (NSComparisonResult) compare: (id) otherFolder
+{
+ NSComparisonResult comparison;
+
+ if ([NSStringFromClass([otherFolder class])
+ isEqualToString: @"SOGoContactLDAPFolder"])
+ comparison = NSOrderedAscending;
+ else
+ comparison = [super compare: otherFolder];
+
+ return comparison;
+}
+
/* folder type */
- (NSString *) folderType