mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-21 19:35:38 +00:00
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:
@@ -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.
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
|
||||
#define $(class) NSClassFromString(class)
|
||||
|
||||
SEL SOGoSelectorForPropertyGetter (NSString *property);
|
||||
SEL SOGoSelectorForPropertySetter (NSString *property);
|
||||
|
||||
@interface SOGoObject : NSObject
|
||||
{
|
||||
WOContext *context;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
- (void) setBaseOCSPath: (NSString *) newOCSPath;
|
||||
|
||||
- (NSArray *) toManyRelationshipKeys;
|
||||
- (NSArray *) subFolders;
|
||||
|
||||
- (NSException *) newFolderWithName: (NSString *) name
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
@interface WORequest (SOGoSOPEUtilities)
|
||||
|
||||
- (BOOL) handledByDefaultHandler;
|
||||
- (NSDictionary *) davPatchedPropertiesWithTopTag: (NSString *) topTag;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user