From b5bc43f248986bc3a5d78716c6f458010d01d378 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Thu, 24 Apr 2008 01:14:21 +0000 Subject: [PATCH] Monotone-Parent: 86a3016fde1fa4a741b945ef29cc0453ddcb73c7 Monotone-Revision: ee924e316a719f77f911fd0f8c793ceec8ccecec Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2008-04-24T01:14:21 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 17 +++++ SoObjects/SOGo/DAVReportMap.plist | 17 +++++ SoObjects/SOGo/SOGoFolder.m | 37 ---------- SoObjects/SOGo/SOGoObject.m | 111 +++++++++++++++++++++++++++--- 4 files changed, 134 insertions(+), 48 deletions(-) create mode 100644 SoObjects/SOGo/DAVReportMap.plist diff --git a/ChangeLog b/ChangeLog index 2af8037dd..5d53d29d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2008-04-23 Wolfgang Sourdeau + * SoObjects/SOGo/SOGoObject.m ([SOGoObject +initialize]): the + module is now a framework and we now load the new DAVReportMap + description file. + ([-davOwner]): the principal URL is now based on the DAV + application URL. + ([SOGoObject + -lookupName:lookupNameinContext:localContextacquire:acquire]): we + now lookup report methods from here (code from SOGoFolder). The + method has changed to refer to the new DAVReportMAP description + file in order to resolve the lookups on self. + ([SOGoObject -davSupportedReportSet]): implemented the new + "supported-report-set" dav method, based on the new mechanism + described above. + + * SoObjects/SOGo/SOGoFolder.m: REPORT lookups are now done + directly from SOGoObject. + * SoObjects/SOGo/SOGoUser.m ([SOGoUser -initWithLogin:newLoginroles:newRoles]): we make sure realUID is not an empty string. diff --git a/SoObjects/SOGo/DAVReportMap.plist b/SoObjects/SOGo/DAVReportMap.plist new file mode 100644 index 000000000..5481dcd07 --- /dev/null +++ b/SoObjects/SOGo/DAVReportMap.plist @@ -0,0 +1,17 @@ +{ /* -*-java-*- */ + /* CalDAV */ + "{urn:ietf:params:xml:ns:caldav}calendar-query" = davCalendarQuery; + "{urn:ietf:params:xml:ns:caldav}calendar-multiget" = davCalendarMultiget; + + /* CardDAV */ + "{urn:ietf:params:xml:ns:carddav}addressbook-query" = davAddressbookQuery; + "{urn:ietf:params:xml:ns:carddav}addressbook-multiget" + = davAddressbookMultiget; + "{urn:ietf:params:xml:ns:carddav}supported-collation-set" + = davSupportedCollectionSet; + + /* Inverse DAV */ + "{urn:inverse:params:xml:ns:inverse-dav}collection-query" + = davCollectionQuery; + "{urn:inverse:params:xml:ns:inverse-dav}acl-query" = davAclQuery; +} diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index b01bfe5a5..1d821ae31 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -24,8 +24,6 @@ #import #import -#import - #import #import "NSString+Utilities.h" @@ -66,41 +64,6 @@ return nil; } -- (id) lookupName: (NSString *) lookupName - inContext: (id) localContext - acquire: (BOOL) acquire -{ - id obj; - NSArray *davNamespaces; - NSDictionary *davInvocation; - NSString *objcMethod; - - obj = [super lookupName: lookupName inContext: localContext - acquire: acquire]; - if (!obj) - { - davNamespaces = [self davNamespaces]; - if ([davNamespaces count] > 0) - { - davInvocation = [lookupName asDavInvocation]; - if (davInvocation - && [davNamespaces - containsObject: [davInvocation objectForKey: @"ns"]]) - { - objcMethod = [[davInvocation objectForKey: @"method"] - davMethodToObjC]; - obj = [[SoSelectorInvocation alloc] - initWithSelectorNamed: - [NSString stringWithFormat: @"%@:", objcMethod] - addContextParameter: YES]; - [obj autorelease]; - } - } - } - - return obj; -} - #warning we should remove this method - (NSArray *) toOneRelationshipKeys { diff --git a/SoObjects/SOGo/SOGoObject.m b/SoObjects/SOGo/SOGoObject.m index 678f6a3c1..eada235b9 100644 --- a/SoObjects/SOGo/SOGoObject.m +++ b/SoObjects/SOGo/SOGoObject.m @@ -28,6 +28,8 @@ #import #import +#import +#import #import #import #import @@ -36,6 +38,8 @@ #import #import #import +#import +#import #import #import #import @@ -56,6 +60,7 @@ #import "NSArray+Utilities.h" #import "NSCalendarDate+SOGo.h" #import "NSDictionary+Utilities.h" +#import "NSObject+Utilities.h" #import "NSString+Utilities.h" #import "SOGoCache.h" #import "SOGoDAVAuthenticator.h" @@ -69,6 +74,8 @@ static BOOL kontactGroupDAV = YES; static BOOL sendACLAdvisories = NO; +static NSDictionary *reportMap = nil; + @interface SOGoObject(Content) - (NSString *) contentAsString; @end @@ -164,6 +171,31 @@ static BOOL sendACLAdvisories = NO; @implementation SOGoObject ++ (void) _loadReportMap +{ + NSFileManager *fm; + NSEnumerator *paths; + NSString *currentPath, *filename; + + [self logWithFormat: @"Loading DAV REPORT map:"]; + + fm = [NSFileManager defaultManager]; + paths = [NSStandardLibraryPaths() objectEnumerator]; + while (!reportMap && (currentPath = [paths nextObject])) + { + filename = [NSString stringWithFormat: @"%@/SOGo-%s.%s/SOGo.framework" + @"/Resources/DAVReportMap.plist", + currentPath, + SOGO_MAJOR_VERSION, SOGO_MINOR_VERSION]; + [self logWithFormat: @" %@", filename]; + if ([fm fileExistsAtPath: filename]) + { + reportMap = [[NSDictionary alloc] initWithContentsOfFile: filename]; + [self logWithFormat: @"found!"]; + } + } +} + + (void) initialize { NSUserDefaults *ud; @@ -172,6 +204,8 @@ static BOOL sendACLAdvisories = NO; kontactGroupDAV = ![ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"]; sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"]; + if (!reportMap) + [self _loadReportMap]; // SoClass security declarations // require View permission to access the root (bound to authenticated ...) @@ -276,8 +310,8 @@ static BOOL sendACLAdvisories = NO; /* DAV ACL properties */ - (NSString *) davOwner { - return [NSString stringWithFormat: @"%@users/%@", - [self rootURLInContext: context], + return [NSString stringWithFormat: @"%@%@", + [WOApplication davURL], [self ownerInContext: nil]]; } @@ -555,12 +589,32 @@ static BOOL sendACLAdvisories = NO; return ma; } +- (NSString *) _reportSelector: (NSString *) reportName +{ + NSString *methodName, *objcMethod, *resultName; + SEL reportSel; + + resultName = nil; + + methodName = [reportMap objectForKey: reportName]; + if (methodName) + { + objcMethod = [NSString stringWithFormat: @"%@:", methodName]; + reportSel = NSSelectorFromString (objcMethod); + if ([self respondsToSelector: reportSel]) + resultName = objcMethod; + } + + return resultName; +} + - (id) lookupName: (NSString *) lookupName inContext: (id) localContext acquire: (BOOL) acquire { id obj; SOGoCache *cache; + NSString *objcMethod; cache = [SOGoCache sharedCache]; obj = [cache objectNamed: lookupName inContainer: self]; @@ -568,10 +622,21 @@ static BOOL sendACLAdvisories = NO; { obj = [[self soClass] lookupKey: lookupName inContext: localContext]; if (obj) + [obj bindToObject: self inContext: localContext]; + else { - [obj bindToObject: self inContext: localContext]; - [cache registerObject: obj withName: lookupName inContainer: self]; + objcMethod = [self _reportSelector: lookupName]; + if (objcMethod) + { + obj = [[SoSelectorInvocation alloc] + initWithSelectorNamed: objcMethod + addContextParameter: YES]; + [obj autorelease]; + } } + + if (obj) + [cache registerObject: obj withName: lookupName inContainer: self]; } return obj; @@ -625,13 +690,14 @@ static BOOL sendACLAdvisories = NO; - (id) DELETEAction: (id) _ctx { - NSException *error; + id result; - if ((error = [self delete]) != nil) - return error; - + result = [self delete]; /* Note: returning 'nil' breaks in SoObjectRequestHandler */ - return [NSNumber numberWithBool:YES]; /* delete worked out ... */ + if (!result) + result = [NSNumber numberWithBool: YES]; /* delete worked out ... */ + + return result; } - (BOOL) isFolderish @@ -1329,8 +1395,10 @@ static BOOL sendACLAdvisories = NO; if ([content length]) { [r setStatus: 207]; - [r setHeader: @"text/xml; charset=\"utf-8\"" forKey: @"content-type"]; - [r appendContentString: @"\r\n"]; + [r setHeader: @"application/xml; charset=\"utf-8\"" + forKey: @"content-type"]; + [r appendContentString: + @"\r\n"]; [r appendContentString: content]; } else @@ -1375,4 +1443,25 @@ static BOOL sendACLAdvisories = NO; return exception; } +- (NSArray *) davSupportedReportSet +{ + NSEnumerator *reportKeys; + NSMutableArray *reportSet; + NSString *currentKey, *currentValue; + + reportSet = [NSMutableArray array]; + + reportKeys = [[reportMap allKeys] objectEnumerator]; + while ((currentKey = [reportKeys nextObject])) + if ([self _reportSelector: currentKey]) + { + currentValue = [[currentKey asDavInvocation] + keysWithFormat: @"<%{method} xmlns=\"%{ns}\"/>"]; + [reportSet addObject: [SoWebDAVValue valueForObject: currentValue + attributes: nil]]; + } + + return [SOGoDAVSet davSetWithArray: reportSet ofValuesTaggedAs: @"report"]; +} + @end /* SOGoObject */