Monotone-Parent: 5db95c823716f08780a1e57b51f753d465c61194

Monotone-Revision: 2af1a4a61509de5048a17987479e677756dc2134

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2009-06-18T20:58:46
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2009-06-18 20:58:46 +00:00
parent a4f46a1205
commit 1e49373ab9
8 changed files with 158 additions and 86 deletions
+14 -1
View File
@@ -1,6 +1,19 @@
2009-06-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/SOGo/DOMNode+SOGo.h: new category module that
* SoObjects/SOGo/DOMNode+SOGo.m
(-flatPropertyNameOfSubElements): new method that returns
flattened ({namespace}tag) names of the first direct child
elements.
* SoObjects/SOGo/SOGoGCSFolder.m (-davSQLFieldsTable): new method
that returns a correspondance table between requested dav
properties and SQL fields required to answer them.
(-parseDAVRequestedProperties:): new method derived from a similar
one in SOGoAppointmentFolder which will return a dictionary of DAV
properties that are requested as well as their corresponding SQL
fields.
* SoObjects/SOGo/DOMNode+SOGo.[hm]: new category module that
implement helper methods for DOM processing.
* SoObjects/Appointments/SOGoAppointmentFolder.m
+42 -77
View File
@@ -37,7 +37,7 @@
#import <NGExtensions/NGLoggerManager.h>
#import <NGExtensions/NSString+misc.h>
#import <GDLContentStore/GCSFolder.h>
#import <DOM/DOMNode.h>
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
#import <EOControl/EOQualifier.h>
#import <EOControl/EOSortOrdering.h>
@@ -52,6 +52,7 @@
#import <NGExtensions/NSObject+Logs.h>
#import <SaxObjC/XMLNamespaces.h>
#import <SOGo/DOMNode+SOGo.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSObject+DAV.h>
#import <SOGo/NSString+Utilities.h>
@@ -1358,7 +1359,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
[filter setObject: textMatch forKey: propName];
}
- (NSDictionary *) _parseCalendarFilter: (id <DOMElement>) filterElement
- (NSDictionary *) _parseCalendarFilter: (DOMElement *) filterElement
{
NSMutableDictionary *filterData;
id <DOMElement> parentNode;
@@ -1397,65 +1398,6 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
return filterData;
}
/* TODO: This method should be generalized to all SOGoGCSFolder-based
classes. */
- (NSDictionary *) _parseRequestedProperties: (id <DOMElement>) parentNode
{
NSMutableDictionary *properties;
NSObject <DOMNodeList> *propList, *children;
NSObject <DOMNode> *currentChild;
unsigned int count, max, count2, max2;
NSString *flatProperty;
NSString *sqlField;
static NSMutableDictionary *davPropsToSQLFields = nil;
if (!davPropsToSQLFields)
{
/* This table is meant to match SQL fields to the properties that
requires them. The fields may NOT be processed directly. This list
is not complete but is at least sufficient for processing requests
from Lightning. */
davPropsToSQLFields = [NSMutableDictionary new];
[davPropsToSQLFields setObject: @"c_content"
forKey: @"{urn:ietf:params:xml:ns:caldav}calendar-data"];
[davPropsToSQLFields setObject: @"c_version"
forKey: @"{DAV:}getetag"];
}
// NSLog (@"parseRequestProperties: %@", [NSDate date]);
properties = [NSMutableDictionary dictionary];
propList = [parentNode getElementsByTagName: @"prop"];
max = [propList length];
for (count = 0; count < max; count++)
{
children = [[propList objectAtIndex: count] childNodes];
max2 = [children length];
for (count2 = 0; count2 < max2; count2++)
{
currentChild = [children objectAtIndex: count2];
if ([currentChild conformsToProtocol: @protocol (DOMElement)])
{
flatProperty = [NSString stringWithFormat: @"{%@}%@",
[currentChild namespaceURI],
[currentChild nodeName]];
sqlField = [davPropsToSQLFields objectForKey: flatProperty];
if (sqlField)
[properties setObject: sqlField forKey: flatProperty];
else
[self errorWithFormat: @"DAV property '%@' not yet supported,"
@" response will be incomplete", flatProperty];
}
}
// while ([children hasChildNodes])
// [properties addObject: [children next]];
}
// NSLog (@"/parseRequestProperties: %@", [NSDate date]);
return properties;
}
- (NSDictionary *) _makeCyclicFilterFrom: (NSDictionary *) filter
{
NSMutableDictionary *rc;
@@ -1472,10 +1414,10 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
return rc;
}
- (NSArray *) _parseCalendarFilters: (id <DOMElement>) parentNode
- (NSArray *) _parseCalendarFilters: (DOMElement *) parentNode
{
id <DOMNodeList> children;
id <DOMElement> node;
DOMElement *element;
NSMutableArray *filters;
NSDictionary *filter;
unsigned int count, max;
@@ -1487,8 +1429,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
max = [children length];
for (count = 0; count < max; count++)
{
node = [children objectAtIndex: count];
filter = [self _parseCalendarFilter: node];
element = [children objectAtIndex: count];
filter = [self _parseCalendarFilter: element];
if (filter)
{
[filters addObject: filter];
@@ -1667,7 +1609,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
propertiesArray = [[properties allKeys] asPointersOfObjects];
propertiesCount = [properties count];
NSLog (@"start");
// NSLog (@"start");
filterList = [filters objectEnumerator];
while ((currentFilter = [filterList nextObject]))
{
@@ -1681,7 +1623,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
title: [currentFilter objectForKey: @"title"]
component: [currentFilter objectForKey: @"name"]
additionalFilters: additionalFilters];
NSLog(@"adding properties");
// NSLog(@"adding properties");
max = [apts count];
buffer = [NSMutableString stringWithCapacity: max * 512];
for (count = 0; count < max; count++)
@@ -1690,20 +1632,37 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
count: propertiesCount
withBaseURL: baseURL
toBuffer: buffer];
NSLog(@"done 1");
// NSLog(@"done 1");
[response appendContentString: buffer];
NSLog(@"done 2");
// NSLog(@"done 2");
}
NSLog (@"stop");
// NSLog (@"stop");
NSZoneFree (NULL, propertiesArray);
}
/* This table is meant to match SQL fields to the properties that requires
them. The fields may NOT be processed directly. This list is not complete
but is at least sufficient for processing requests from Lightning. */
- (NSDictionary *) davSQLFieldsTable
{
static NSMutableDictionary *davSQLFieldsTable = nil;
if (!davSQLFieldsTable)
{
davSQLFieldsTable = [[super davSQLFieldsTable] mutableCopy];
[davSQLFieldsTable setObject: @"c_content"
forKey: @"{" XMLNS_CALDAV @"}calendar-data"];
}
return davSQLFieldsTable;
}
- (id) davCalendarQuery: (id) queryContext
{
WOResponse *r;
id <DOMDocument> document;
id <DOMElement> documentElement;
DOMElement *documentElement, *propElement;
r = [context response];
[r setStatus: 207];
@@ -1713,11 +1672,14 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
[r setHeader: @"no-cache" forKey: @"cache-control"];
[r appendContentString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[r appendContentString: @"<D:multistatus xmlns:D=\"DAV:\""
@" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">"];
@" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">"];
document = [[context request] contentAsDOMDocument];
documentElement = [document documentElement];
[self _appendComponentProperties: [self _parseRequestedProperties: documentElement]
documentElement = (DOMElement *) [document documentElement];
propElement = [documentElement firstElementWithTag: @"prop"
inNamespace: XMLNS_WEBDAV];
[self _appendComponentProperties: [self parseDAVRequestedProperties: propElement]
matchingFilters: [self _parseCalendarFilters: documentElement]
toResponse: r];
[r appendContentString:@"</D:multistatus>"];
@@ -1905,7 +1867,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
{
WOResponse *r;
id <DOMDocument> document;
id <DOMElement> documentElement;
DOMElement *documentElement, *propElement;
r = [context response];
[r setStatus: 207];
@@ -1918,8 +1880,11 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
@" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">"];
document = [[context request] contentAsDOMDocument];
documentElement = [document documentElement];
[self _appendComponentProperties: [self _parseRequestedProperties: documentElement]
documentElement = (DOMElement *) [document documentElement];
propElement = [documentElement firstElementWithTag: @"prop"
inNamespace: @"DAV:"];
[self _appendComponentProperties: [self parseDAVRequestedProperties: propElement]
matchingURLs: [documentElement getElementsByTagName: @"href"]
toResponse: r];
[r appendContentString:@"</D:multistatus>"];
+2
View File
@@ -14,6 +14,8 @@
"{DAV:}principal-match" = davPrincipalMatch;
"{DAV:}principal-property-search" = davPrincipalPropertySearch;
"{DAV:}principal-search-property-set" = davPrincipalSearchPropertySet;
"{DAV:}principal-search-property-set" = davPrincipalSearchPropertySet;
"{DAV:}sync-collection" = davSyncCollection;
/* Inverse DAV */
"{urn:inverse:params:xml:ns:inverse-dav}collection-query"
+8 -4
View File
@@ -25,15 +25,19 @@
#import <DOM/DOMNode.h>
@interface NGDOMNodeWithChildren (SOGoDOMExtensions) < DOMNode >
@class DOMElement;
@interface NGDOMNodeWithChildren (SOGoDOMExtensions)
- (id <DOMNodeList>) childElementsWithTag: (NSString *) tagName;
- (id <DOMNodeList>) childElementsWithTag: (NSString *) tagName
inNamespace: (NSString *) namespace;
- (id <DOMElement>) firstElementWithTag: (NSString *) tagName;
- (id <DOMElement>) firstElementWithTag: (NSString *) tagName
inNamespace: (NSString *) namespace;
- (DOMElement *) firstElementWithTag: (NSString *) tagName;
- (DOMElement *) firstElementWithTag: (NSString *) tagName
inNamespace: (NSString *) namespace;
- (NSArray *) flatPropertyNameOfSubElements;
@end
+31 -4
View File
@@ -59,11 +59,11 @@
return [self childElementsWithTag: tagName inNamespace: nil];
}
- (id <DOMElement>) firstElementWithTag: (NSString *) tagName
inNamespace: (NSString *) namespace
- (DOMElement *) firstElementWithTag: (NSString *) tagName
inNamespace: (NSString *) namespace
{
id <DOMNodeList> nodes;
id <DOMElement> node, currentElement;
DOMElement *node, *currentElement;
unsigned int count, max;
node = nil;
@@ -83,9 +83,36 @@
return node;
}
- (id <DOMElement>) firstElementWithTag: (NSString *) tagName
- (DOMElement *) firstElementWithTag: (NSString *) tagName
{
return [self firstElementWithTag: tagName inNamespace: nil];
}
- (NSArray *) flatPropertyNameOfSubElements
{
NSMutableArray *propertyNames;
id <DOMNodeList> children;
DOMElement *currentElement;
NSString *property;
unsigned int count, max;
propertyNames = [NSMutableArray array];
children = [self childNodes];
max = [children length];
for (count = 0; count < max; count++)
{
currentElement = [children objectAtIndex: count];
if ([currentElement nodeType] == DOM_ELEMENT_NODE)
{
property = [NSString stringWithFormat: @"{%@}%@",
[currentElement namespaceURI],
[currentElement tagName]];
[propertyNames addObject: property];
}
}
return propertyNames;
}
@end
+4
View File
@@ -55,6 +55,8 @@ SOGo_HEADER_FILES = \
NSDictionary+BSJSONAdditions.h \
NSScanner+BSJSONAdditions.h \
\
DOMNode+SOGo.h \
\
WORequest+SOGo.h \
WOContext+SOGo.h
@@ -101,6 +103,8 @@ SOGo_OBJC_FILES = \
NSDictionary+BSJSONAdditions.m \
NSScanner+BSJSONAdditions.m \
\
DOMNode+SOGo.m \
\
WORequest+SOGo.m \
WOContext+SOGo.m
+6
View File
@@ -33,6 +33,8 @@
@class WOContext;
@class WOResponse;
@class DOMElement;
/*
SOGoGCSFolder
@@ -105,6 +107,10 @@
/* advisories */
- (void) sendFolderAdvisoryTemplate: (NSString *) template;
/* DAV */
- (NSDictionary *) davSQLFieldsTable;
- (NSDictionary *) parseDAVRequestedProperties: (DOMElement *) propElement;
@end
#endif /* __SOGo_SOGoGCSFolder_H__ */
+51
View File
@@ -40,6 +40,7 @@
#import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <DOM/DOMElement.h>
#import <DOM/DOMProtocols.h>
#import <EOControl/EOFetchSpecification.h>
#import <EOControl/EOQualifier.h>
@@ -58,6 +59,7 @@
#import "NSObject+DAV.h"
#import "NSString+Utilities.h"
#import "DOMNode+SOGo.h"
#import "SOGoContentObject.h"
#import "SOGoGroup.h"
#import "SOGoParentFolder.h"
@@ -791,6 +793,55 @@ static NSArray *childRecordFields = nil;
inContext: queryContext];
}
- (NSDictionary *) davSQLFieldsTable
{
static NSMutableDictionary *davSQLFieldsTable = nil;
if (!davSQLFieldsTable)
{
davSQLFieldsTable = [NSMutableDictionary new];
[davSQLFieldsTable setObject: @"c_version" forKey: @"{DAV:}getetag"];
}
return davSQLFieldsTable;
}
- (NSDictionary *) _davSQLFieldsForProperties: (NSArray *) properties
{
NSMutableDictionary *davSQLFields;
NSDictionary *davSQLFieldsTable;
NSString *sqlField, *property;
unsigned int count, max;
davSQLFieldsTable = [self davSQLFieldsTable];
max = [properties count];
davSQLFields = [NSMutableDictionary dictionaryWithCapacity: max];
for (count = 0; count < max; count++)
{
property = [properties objectAtIndex: count];
sqlField = [davSQLFieldsTable objectForKey: property];
if (sqlField)
[davSQLFields setObject: sqlField forKey: property];
else
[self errorWithFormat: @"DAV property '%@' has no matching SQL field,"
@" response will be incomplete", property];
}
return davSQLFields;
}
- (NSDictionary *) parseDAVRequestedProperties: (DOMElement *) propElement
{
NSArray *properties;
NSDictionary *sqlFieldsTable;
properties = [propElement flatPropertyNameOfSubElements];
sqlFieldsTable = [self _davSQLFieldsForProperties: properties];
return sqlFieldsTable;
}
/* handling acls from quick tables */
- (void) initializeQuickTablesAclsInContext: (WOContext *) localContext
{