diff --git a/ChangeLog b/ChangeLog index fef1e0965..9d005c7a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2010-04-23 Wolfgang Sourdeau + * Main/SOGo+DAV.m (-davPrincipalPropertySearch:): restored method. + + * SoObjects/SOGo/SOGoUserFolder.m (-collectionDavKey:matches:): + moved this tester method for REPORT queries from SOGo+DAV.m. + * Tools/SOGoSockDOperation.m (-_performSearch): we now support an additional identifier in the object DN, for specifying specific objects. diff --git a/Main/SOGo+DAV.m b/Main/SOGo+DAV.m index 1764c7728..6369e6855 100644 --- a/Main/SOGo+DAV.m +++ b/Main/SOGo+DAV.m @@ -238,165 +238,158 @@ return r; } -// - (void) _fillMatches: (NSMutableDictionary *) matches -// fromElement: (NSObject *) searchElement -// { -// NSObject *list; -// NSObject *valueNode; -// NSArray *elements; -// NSString *property, *match; +- (void) _fillMatches: (NSMutableDictionary *) matches + fromElement: (NSObject *) searchElement +{ + NSObject *list; + NSObject *valueNode; + NSArray *elements; + NSString *property, *match; -// list = [searchElement getElementsByTagName: @"prop"]; -// if ([list length]) -// { -// elements = [self domNode: [list objectAtIndex: 0] -// getChildNodesByType: DOM_ELEMENT_NODE]; -// if ([elements count]) -// { -// valueNode = [elements objectAtIndex: 0]; -// property = [NSString stringWithFormat: @"{%@}%@", -// [valueNode namespaceURI], -// [valueNode nodeName]]; -// } -// } -// list = [searchElement getElementsByTagName: @"match"]; -// if ([list length]) -// { -// valueNode = [[list objectAtIndex: 0] firstChild]; -// match = [valueNode nodeValue]; -// } + list = [searchElement getElementsByTagName: @"prop"]; + if ([list length]) + { + elements = [self domNode: [list objectAtIndex: 0] + getChildNodesByType: DOM_ELEMENT_NODE]; + if ([elements count]) + { + valueNode = [elements objectAtIndex: 0]; + property = [NSString stringWithFormat: @"{%@}%@", + [valueNode namespaceURI], + [valueNode nodeName]]; + } + } + list = [searchElement getElementsByTagName: @"match"]; + if ([list length]) + { + valueNode = [[list objectAtIndex: 0] firstChild]; + match = [valueNode nodeValue]; + } -// [matches setObject: match forKey: property]; -// } + [matches setObject: match forKey: property]; +} -// - (void) _fillProperties: (NSMutableArray *) properties -// fromElement: (NSObject *) propElement -// { -// NSEnumerator *elements; -// NSObject *propNode; -// NSString *property; +- (void) _fillProperties: (NSMutableArray *) properties + fromElement: (NSObject *) propElement +{ + NSEnumerator *elements; + NSObject *propNode; + NSString *property; -// elements = [[self domNode: propElement -// getChildNodesByType: DOM_ELEMENT_NODE] -// objectEnumerator]; -// while ((propNode = [elements nextObject])) -// { -// property = [NSString stringWithFormat: @"{%@}%@", -// [propNode namespaceURI], -// [propNode nodeName]]; -// [properties addObject: property]; -// } -// } + elements = [[self domNode: propElement + getChildNodesByType: DOM_ELEMENT_NODE] + objectEnumerator]; + while ((propNode = [elements nextObject])) + { + property = [NSString stringWithFormat: @"{%@}%@", + [propNode namespaceURI], + [propNode nodeName]]; + [properties addObject: property]; + } +} -// - (void) _fillPrincipalMatches: (NSMutableDictionary *) matches -// andProperties: (NSMutableArray *) properties -// fromElement: (NSObject *) documentElement -// { -// NSEnumerator *children; -// NSObject *currentElement; -// NSString *tag; +- (void) _fillPrincipalMatches: (NSMutableDictionary *) matches + andProperties: (NSMutableArray *) properties + fromElement: (NSObject *) documentElement +{ + NSEnumerator *children; + NSObject *currentElement; + NSString *tag; -// children = [[self domNode: documentElement -// getChildNodesByType: DOM_ELEMENT_NODE] -// objectEnumerator]; -// while ((currentElement = [children nextObject])) -// { -// tag = [currentElement tagName]; -// if ([tag isEqualToString: @"property-search"]) -// [self _fillMatches: matches fromElement: currentElement]; -// else if ([tag isEqualToString: @"prop"]) -// [self _fillProperties: properties fromElement: currentElement]; -// else -// [self errorWithFormat: @"principal-property-search: unknown tag '%@'", -// tag]; -// } -// } + children = [[self domNode: documentElement + getChildNodesByType: DOM_ELEMENT_NODE] + objectEnumerator]; + while ((currentElement = [children nextObject])) + { + tag = [currentElement tagName]; + if ([tag isEqualToString: @"property-search"]) + [self _fillMatches: matches fromElement: currentElement]; + else if ([tag isEqualToString: @"prop"]) + [self _fillProperties: properties fromElement: currentElement]; + else + [self errorWithFormat: @"principal-property-search: unknown tag '%@'", + tag]; + } +} #warning this is a bit ugly, as usual -// - (void) _fillCollections: (NSMutableArray *) collections -// withCalendarHomeSetMatching: (NSString *) value -// inContext: (WOContext *) localContext -// { -// SOGoUserFolder *collection; -// NSRange substringRange; +- (void) _fillCollections: (NSMutableArray *) collections + withCalendarHomeSetMatching: (NSString *) value + inContext: (WOContext *) localContext +{ + SOGoUserFolder *collection; + NSRange substringRange; -// substringRange = [value rangeOfString: @"/SOGo/dav/"]; -// value = [value substringFromIndex: NSMaxRange (substringRange)]; -// substringRange = [value rangeOfString: @"/Calendar"]; -// value = [value substringToIndex: substringRange.location]; -// collection = [[SOGoUser userWithLogin: value] -// homeFolderInContext: localContext]; -// if (collection) -// [collections addObject: collection]; -// } + substringRange = [value rangeOfString: @"/SOGo/dav/"]; + value = [value substringFromIndex: NSMaxRange (substringRange)]; + substringRange = [value rangeOfString: @"/Calendar"]; + value = [value substringToIndex: substringRange.location]; + collection = [[SOGoUser userWithLogin: value] + homeFolderInContext: localContext]; + if (collection) + [collections addObject: collection]; +} -// - (NSMutableArray *) _firstPrincipalCollectionsWhere: (NSString *) key -// matches: (NSString *) value -// inContext: (WOContext *) localContext -// { -// NSMutableArray *collections; +- (NSMutableArray *) _firstPrincipalCollectionsWhere: (NSString *) key + matches: (NSString *) value + inContext: (WOContext *) localContext +{ + NSMutableArray *collections; -// collections = [NSMutableArray array]; -// if ([key -// isEqualToString: @"{urn:ietf:params:xml:ns:caldav}calendar-home-set"]) -// [self _fillCollections: collections withCalendarHomeSetMatching: value -// inContext: localContext]; -// else -// [self errorWithFormat: @"principal-property-search: unhandled key '%@'", -// key]; + collections = [NSMutableArray array]; + if ([key + isEqualToString: @"{urn:ietf:params:xml:ns:caldav}calendar-home-set"]) + [self _fillCollections: collections withCalendarHomeSetMatching: value + inContext: localContext]; + else + [self errorWithFormat: @"principal-property-search: unhandled key '%@'", + key]; -// return collections; -// } + return collections; +} -// #warning unused stub -// - (BOOL) collectionDavKey: (NSString *) key -// matches: (NSString *) value -// { -// return YES; -// } +- (void) _principalCollections: (NSMutableArray **) baseCollections + where: (NSString *) key + matches: (NSString *) value + inContext: (WOContext *) localContext +{ + SOGoUserFolder *currentCollection; + unsigned int count, max; -// - (void) _principalCollections: (NSMutableArray **) baseCollections -// where: (NSString *) key -// matches: (NSString *) value -// inContext: (WOContext *) localContext -// { -// SOGoUserFolder *currentCollection; -// unsigned int count, max; + if (!*baseCollections) + *baseCollections = [self _firstPrincipalCollectionsWhere: key + matches: value + inContext: localContext]; + else + { + max = [*baseCollections count]; + for (count = max; count > 0; count--) + { + currentCollection = [*baseCollections objectAtIndex: count - 1]; + if (![currentCollection collectionDavKey: key matches: value]) + [*baseCollections removeObjectAtIndex: count - 1]; + } + } +} -// if (!*baseCollections) -// *baseCollections = [self _firstPrincipalCollectionsWhere: key -// matches: value -// inContext: localContext]; -// else -// { -// max = [*baseCollections count]; -// for (count = max; count > 0; count--) -// { -// currentCollection = [*baseCollections objectAtIndex: count - 1]; -// if (![currentCollection collectionDavKey: key matches: value]) -// [*baseCollections removeObjectAtIndex: count - 1]; -// } -// } -// } +- (NSArray *) _principalCollectionsMatching: (NSDictionary *) matches + inContext: (WOContext *) localContext +{ + NSMutableArray *collections; + NSEnumerator *allKeys; + NSString *currentKey; -// - (NSArray *) _principalCollectionsMatching: (NSDictionary *) matches -// inContext: (WOContext *) localContext -// { -// NSMutableArray *collections; -// NSEnumerator *allKeys; -// NSString *currentKey; + collections = nil; -// collections = nil; + allKeys = [[matches allKeys] objectEnumerator]; + while ((currentKey = [allKeys nextObject])) + [self _principalCollections: &collections + where: currentKey + matches: [matches objectForKey: currentKey] + inContext: localContext]; -// allKeys = [[matches allKeys] objectEnumerator]; -// while ((currentKey = [allKeys nextObject])) -// [self _principalCollections: &collections -// where: currentKey -// matches: [matches objectForKey: currentKey] -// inContext: localContext]; - -// return collections; -// } + return collections; +} /* @@ -420,96 +413,95 @@ */ -// - (void) _appendProperties: (NSArray *) properties -// ofCollection: (SOGoUserFolder *) collection -// toResponses: (NSMutableArray *) responses -// { -// unsigned int count, max; -// SEL methodSel; -// NSString *currentProperty; -// id currentValue; -// NSMutableArray *response, *props; -// NSDictionary *keyTuple; +- (void) _appendProperties: (NSArray *) properties + ofCollection: (SOGoUserFolder *) collection + toResponses: (NSMutableArray *) responses +{ + unsigned int count, max; + SEL methodSel; + NSString *currentProperty; + id currentValue; + NSMutableArray *response, *props; + NSDictionary *keyTuple; -// response = [NSMutableArray array]; -// [response addObject: davElementWithContent (@"href", XMLNS_WEBDAV, -// [collection davURLAsString])]; -// props = [NSMutableArray array]; -// max = [properties count]; -// for (count = 0; count < max; count++) -// { -// currentProperty = [properties objectAtIndex: count]; -// methodSel = SOGoSelectorForPropertyGetter (currentProperty); -// if (methodSel && [collection respondsToSelector: methodSel]) -// { -// currentValue = [collection performSelector: methodSel]; -// #warning evil eVIL EVIl! -// if ([currentValue isKindOfClass: [NSArray class]]) -// { -// currentValue = [currentValue objectAtIndex: 0]; -// currentValue -// = davElementWithContent ([currentValue objectAtIndex: 0], -// [currentValue objectAtIndex: 1], -// [currentValue objectAtIndex: 3]); -// } -// keyTuple = [currentProperty asWebDAVTuple]; -// [props addObject: davElementWithContent ([keyTuple objectForKey: @"method"], -// [keyTuple objectForKey: @"ns"], -// currentValue)]; -// } -// } -// [response addObject: davElementWithContent (@"propstat", XMLNS_WEBDAV, -// davElementWithContent -// (@"prop", XMLNS_WEBDAV, -// props))]; -// [responses addObject: davElementWithContent (@"response", XMLNS_WEBDAV, -// response)]; -// } + response = [NSMutableArray array]; + [response addObject: davElementWithContent (@"href", XMLNS_WEBDAV, + [collection davURLAsString])]; + props = [NSMutableArray array]; + max = [properties count]; + for (count = 0; count < max; count++) + { + currentProperty = [properties objectAtIndex: count]; + methodSel = SOGoSelectorForPropertyGetter (currentProperty); + if (methodSel && [collection respondsToSelector: methodSel]) + { + currentValue = [collection performSelector: methodSel]; + #warning evil eVIL EVIl! + if ([currentValue isKindOfClass: [NSArray class]]) + { + currentValue = [currentValue objectAtIndex: 0]; + currentValue + = davElementWithContent ([currentValue objectAtIndex: 0], + [currentValue objectAtIndex: 1], + [currentValue objectAtIndex: 3]); + } + keyTuple = [currentProperty asWebDAVTuple]; + [props addObject: davElementWithContent ([keyTuple objectForKey: @"method"], + [keyTuple objectForKey: @"ns"], + currentValue)]; + } + } + [response addObject: davElementWithContent (@"propstat", XMLNS_WEBDAV, + davElementWithContent + (@"prop", XMLNS_WEBDAV, + props))]; + [responses addObject: davElementWithContent (@"response", XMLNS_WEBDAV, + response)]; +} -// - (void) _appendProperties: (NSArray *) properties -// ofCollections: (NSArray *) collections -// toResponse: (WOResponse *) response -// { -// NSDictionary *mStatus; -// NSMutableArray *responses; -// unsigned int count, max; +- (void) _appendProperties: (NSArray *) properties + ofCollections: (NSArray *) collections + toResponse: (WOResponse *) response +{ + NSDictionary *mStatus; + NSMutableArray *responses; + unsigned int count, max; -// max = [collections count]; -// responses = [NSMutableArray arrayWithCapacity: max]; -// for (count = 0; count < max; count++) -// [self _appendProperties: properties -// ofCollection: [collections objectAtIndex: count] -// toResponses: responses]; -// mStatus = davElementWithContent (@"multistatus", XMLNS_WEBDAV, responses); -// [response appendContentString: [mStatus asWebDavStringWithNamespaces: nil]]; -// } + max = [collections count]; + responses = [NSMutableArray arrayWithCapacity: max]; + for (count = 0; count < max; count++) + [self _appendProperties: properties + ofCollection: [collections objectAtIndex: count] + toResponses: responses]; + mStatus = davElementWithContent (@"multistatus", XMLNS_WEBDAV, responses); + [response appendContentString: [mStatus asWebDavStringWithNamespaces: nil]]; +} /* rfc3744, should be moved into SOGoUserFolder */ +- (WOResponse *) davPrincipalPropertySearch: (WOContext *) localContext +{ + NSObject *document; + NSObject *documentElement; + NSArray *collections; + NSMutableDictionary *matches; + NSMutableArray *properties; + WOResponse *r; -// - (WOResponse *) davPrincipalPropertySearch: (WOContext *) localContext -// { -// NSObject *document; -// NSObject *documentElement; -// NSArray *collections; -// NSMutableDictionary *matches; -// NSMutableArray *properties; -// WOResponse *r; + document = [[localContext request] contentAsDOMDocument]; + documentElement = [document documentElement]; -// document = [[localContext request] contentAsDOMDocument]; -// documentElement = [document documentElement]; + matches = [NSMutableDictionary dictionary]; + properties = [NSMutableArray array]; + [self _fillPrincipalMatches: matches andProperties: properties + fromElement: documentElement]; + collections = [self _principalCollectionsMatching: matches + inContext: localContext]; + r = [localContext response]; + [r prepareDAVResponse]; + [self _appendProperties: properties ofCollections: collections + toResponse: r]; -// matches = [NSMutableDictionary dictionary]; -// properties = [NSMutableArray array]; -// [self _fillPrincipalMatches: matches andProperties: properties -// fromElement: documentElement]; -// collections = [self _principalCollectionsMatching: matches -// inContext: localContext]; -// r = [localContext response]; -// [r prepareDAVResponse]; -// [self _appendProperties: properties ofCollections: collections -// toResponse: r]; - -// return r; -// } + return r; +} @end diff --git a/SoObjects/SOGo/SOGoUserFolder.h b/SoObjects/SOGo/SOGoUserFolder.h index f4c64f79b..9a2682921 100644 --- a/SoObjects/SOGo/SOGoUserFolder.h +++ b/SoObjects/SOGo/SOGoUserFolder.h @@ -58,6 +58,9 @@ - (NSArray *) davPrincipalURL; +- (BOOL) collectionDavKey: (NSString *) key + matches: (NSString *) value; + @end #endif /* __SOGo_SOGoUserFolder_H__ */ diff --git a/SoObjects/SOGo/SOGoUserFolder.m b/SoObjects/SOGo/SOGoUserFolder.m index db8263f4f..91c10f532 100644 --- a/SoObjects/SOGo/SOGoUserFolder.m +++ b/SoObjects/SOGo/SOGoUserFolder.m @@ -634,4 +634,12 @@ return nil; } +#warning unused stub +- (BOOL) collectionDavKey: (NSString *) key + matches: (NSString *) value +{ + return YES; +} + + @end /* SOGoUserFolder */