Monotone-Parent: 10cd99d7bb60f6b8cd1fe6b59a1c9a647dd0ba3b

Monotone-Revision: dcb58071ad12a3e87d2a061647e9558e70bb9775

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2008-07-09T21:09:08
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2008-07-09 21:09:08 +00:00
parent 13daab061a
commit 5e1fb58ab9
8 changed files with 231 additions and 50 deletions
+14
View File
@@ -1,5 +1,19 @@
2008-07-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentFolders.m ([SOGoAppointmentFolders -davCreateCalendarCollection:newNameinContext:createContext]):
new method that execute a "MKCALENDAR" request.
* SoObjects/SOGo/SOGoObject.m (SOGoSelectorForPropertyGetter): new
function that returns the selector for the getter method for the
specified property.
(SOGoSelectorForPropertySetter): same as above for the setter
method.
* SoObjects/SOGo/WORequest+SOGo.m ([WORequest
-davPatchedPropertiesWithTopTag:topTag]): new category method to
help with parsing properties modified or removed from PROPPATCH
methods and alike.
* SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject
-PUTAction:_ctx]): increment the version number only if the record
is not new.
+1 -31
View File
@@ -891,36 +891,6 @@ static Class sogoAppointmentFolderKlass = Nil;
#warning we should use the EOFetchSpecification for that!!! (see doPROPFIND:)
#warning components in calendar-data query are ignored
static inline SEL
_selectorForProperty (NSString *property)
{
static NSMutableDictionary *methodMap = nil;
SEL propSel;
NSValue *propPtr;
NSDictionary *map;
NSString *methodName;
if (!methodMap)
methodMap = [NSMutableDictionary new];
propPtr = [methodMap objectForKey: property];
if (propPtr)
propSel = [propPtr pointerValue];
else
{
map = [sogoAppointmentFolderKlass defaultWebDAVAttributeMap];
methodName = [map objectForKey: property];
if (methodName)
{
propSel = NSSelectorFromString (methodName);
if (propSel)
[methodMap setObject: [NSValue valueWithPointer: propSel]
forKey: property];
}
}
return propSel;
}
- (NSString *) _nodeTagForProperty: (NSString *) property
{
NSString *namespace, *nodeName, *nsRep;
@@ -984,7 +954,7 @@ _selectorForProperty (NSString *property)
currentValue = values;
while (*currentProperty)
{
methodSel = _selectorForProperty (*currentProperty);
methodSel = SOGoSelectorForPropertyGetter (*currentProperty);
if (methodSel && [sogoObject respondsToSelector: methodSel])
*currentValue = [[sogoObject performSelector: methodSel]
stringByEscapingXMLString];
+85 -19
View File
@@ -21,12 +21,14 @@
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest+So.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <SOGo/WORequest+SOGo.h>
#import "SOGoAppointmentFolder.h"
#import "SOGoAppointmentFolders.h"
@@ -48,40 +50,104 @@
return [self labelForKey: @"Personal Calendar"];
}
- (id) lookupName: (NSString *) name
inContext: (WOContext *) lookupContext
acquire: (BOOL) acquire
- (NSString *) _fetchPropertyWithName: (NSString *) propertyName
inArray: (NSArray *) section
{
id obj;
WORequest *rq;
NSObject <DOMElement> *currentElement;
NSString *currentName, *property;
NSEnumerator *elements;
NSObject <DOMNodeList> *values;
obj = [super lookupName: name inContext: lookupContext acquire: NO];
property = nil;
rq = [context request];
if ([rq isSoWebDAVRequest]
&& [[rq method] isEqualToString: @"MKCALENDAR"])
elements = [section objectEnumerator];
while (!property && (currentElement = [elements nextObject]))
{
if (obj)
obj = [NSException exceptionWithHTTPStatus: 403];
else
currentName = [NSString stringWithFormat: @"{%@}%@",
[currentElement namespaceURI],
[currentElement nodeName]];
if ([currentName isEqualToString: propertyName])
{
obj = [self newFolderWithName: name andNameInContainer: name];
if (!obj)
obj = [super lookupName: name inContext: lookupContext acquire: NO];
values = [currentElement childNodes];
if ([values length])
property = [[values objectAtIndex: 0] nodeValue];
}
}
return obj;
return property;
}
- (id) doMKCALENDAR: (id) test
#warning this method may be useful at a higher level
#warning not all values are simple strings...
- (NSException *) _applyMkCalendarProperties: (NSArray *) properties
toObject: (SOGoObject *) newFolder
{
NSEnumerator *allProperties;
NSObject <DOMElement> *currentProperty;
NSObject <DOMNodeList> *values;
NSString *value, *currentName;
SEL methodSel;
allProperties = [properties objectEnumerator];
while ((currentProperty = [allProperties nextObject]))
{
values = [currentProperty childNodes];
if ([values length])
{
value = [[values objectAtIndex: 0] nodeValue];
currentName = [NSString stringWithFormat: @"{%@}%@",
[currentProperty namespaceURI],
[currentProperty nodeName]];
methodSel = SOGoSelectorForPropertySetter (currentName);
if ([newFolder respondsToSelector: methodSel])
[newFolder performSelector: methodSel
withObject: value];
}
}
return nil;
}
- (id) MKCALENDARAction: (id) localContext
- (NSException *) davCreateCalendarCollection: (NSString *) newName
inContext: (id) createContext
{
return nil;
NSArray *subfolderNames, *setProperties;
NSString *content, *newDisplayName;
NSDictionary *properties;
NSException *error;
SOGoAppointmentFolder *newFolder;
subfolderNames = [self toManyRelationshipKeys];
if ([subfolderNames containsObject: newName])
{
content = [NSString stringWithFormat:
@"A collection named '%@' already exists.",
newName];
error = [NSException exceptionWithHTTPStatus: 403
reason: content];
}
else
{
properties = [[createContext request]
davPatchedPropertiesWithTopTag: @"mkcalendar"];
setProperties = [properties objectForKey: @"set"];
newDisplayName = [self _fetchPropertyWithName: @"{DAV:}displayname"
inArray: setProperties];
if (![newDisplayName length])
newDisplayName = newName;
error
= [self newFolderWithName: newDisplayName andNameInContainer: newName];
if (!error)
{
newFolder = [self lookupName: newName
inContext: createContext
acquire: NO];
error = [self _applyMkCalendarProperties: setProperties
toObject: newFolder];
}
}
return error;
}
#warning THIS CAUSES LIGHTNING TO FAIL (that is why its commented out)
+3
View File
@@ -62,6 +62,9 @@
#define $(class) NSClassFromString(class)
SEL SOGoSelectorForPropertyGetter (NSString *property);
SEL SOGoSelectorForPropertySetter (NSString *property);
@interface SOGoObject : NSObject
{
WOContext *context;
+58
View File
@@ -71,6 +71,64 @@ static BOOL kontactGroupDAV = YES;
static BOOL sendACLAdvisories = NO;
static NSDictionary *reportMap = nil;
static NSMutableDictionary *setterMap = nil;
static NSMutableDictionary *getterMap = nil;
SEL SOGoSelectorForPropertyGetter (NSString *property)
{
SEL propSel;
NSValue *propPtr;
NSDictionary *map;
NSString *methodName;
if (!getterMap)
getterMap = [NSMutableDictionary new];
propPtr = [getterMap objectForKey: property];
if (propPtr)
propSel = [propPtr pointerValue];
else
{
map = [SOGoObject defaultWebDAVAttributeMap];
methodName = [map objectForKey: property];
if (methodName)
{
propSel = NSSelectorFromString (methodName);
if (propSel)
[getterMap setObject: [NSValue valueWithPointer: propSel]
forKey: property];
}
}
return propSel;
}
SEL SOGoSelectorForPropertySetter (NSString *property)
{
SEL propSel;
NSValue *propPtr;
NSDictionary *map;
NSString *methodName;
if (!setterMap)
setterMap = [NSMutableDictionary new];
propPtr = [setterMap objectForKey: property];
if (propPtr)
propSel = [propPtr pointerValue];
else
{
map = [SOGoObject defaultWebDAVAttributeMap];
methodName = [map objectForKey: property];
if (methodName)
{
propSel = NSSelectorFromString ([methodName davSetterName]);
if (propSel)
[setterMap setObject: [NSValue valueWithPointer: propSel]
forKey: property];
}
}
return propSel;
}
@implementation SOGoObject
+1
View File
@@ -43,6 +43,7 @@
- (void) setBaseOCSPath: (NSString *) newOCSPath;
- (NSArray *) toManyRelationshipKeys;
- (NSArray *) subFolders;
- (NSException *) newFolderWithName: (NSString *) name
+1
View File
@@ -28,6 +28,7 @@
@interface WORequest (SOGoSOPEUtilities)
- (BOOL) handledByDefaultHandler;
- (NSDictionary *) davPatchedPropertiesWithTopTag: (NSString *) topTag;
@end
+68
View File
@@ -20,9 +20,13 @@
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSDictionary.h>
#import <NGObjWeb/SoObjectRequestHandler.h>
#import <NGObjWeb/WOApplication.h>
#import <DOM/DOMProtocols.h>
#import "WORequest+SOGo.h"
@implementation WORequest (SOGoSOPEUtilities)
@@ -33,4 +37,68 @@
return (![requestHandlerKey isEqualToString: @"dav"]);
}
- (NSArray *) _propertiesOfElement: (id <DOMElement>) startElement
underTag: (NSString *) tag
{
id <DOMNodeList> list;
id <DOMElement> tagElement;
NSObject <DOMNode> *currentNode;
NSMutableArray *properties;
unsigned int count, max;
properties = nil;
list = [startElement getElementsByTagName: tag];
if ([list length])
{
tagElement = [list objectAtIndex: 0];
list = [tagElement getElementsByTagName: @"prop"];
if ([list length])
{
tagElement = [list objectAtIndex: 0];
properties = [NSMutableArray array];
list = [tagElement childNodes];
max = [list length];
for (count = 0; count < max; count++)
{
currentNode = [list objectAtIndex: count];
if ([currentNode conformsToProtocol: @protocol (DOMElement)])
[properties addObject: currentNode];
}
}
}
return properties;
}
- (NSDictionary *) davPatchedPropertiesWithTopTag: (NSString *) topTag
{
NSMutableDictionary *patchedProperties;
NSArray *props;
id <DOMDocument> element;
id <DOMElement> startElement;
NSObject <DOMNodeList> *list;
patchedProperties = nil;
if (!topTag)
topTag = @"propertyupdate";
element = [self contentAsDOMDocument];
list = [element getElementsByTagName: topTag];
if ([list length])
{
startElement = [list objectAtIndex: 0];
patchedProperties = [NSMutableDictionary dictionary];
props = [self _propertiesOfElement: startElement
underTag: @"set"];
if (props)
[patchedProperties setObject: props forKey: @"set"];
props = [self _propertiesOfElement: startElement
underTag: @"remove"];
if (props)
[patchedProperties setObject: props forKey: @"remove"];
}
return patchedProperties;
}
@end