mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-07-10 10:55:08 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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>"];
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user