Monotone-Parent: 4a0075d77198c329e5e471528db155313b163846
Monotone-Revision: baff79ac3da07f610290a1d61e142dace0bb02a4 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2008-06-13T19:59:22 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
22a6e527e0
commit
40e2a71a0e
|
@ -1,5 +1,14 @@
|
||||||
2008-06-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2008-06-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject
|
||||||
|
+objectWithRecord:objectRecordinContainer:newContainer]): new
|
||||||
|
constructor that instantiate an object based on the data found in
|
||||||
|
the corresponding database record.
|
||||||
|
([SOGoContentObject -setOCSPath:newOCSPath]): removed this method and
|
||||||
|
other OCS related ones, since we no longer fetch the record data
|
||||||
|
from here. Indeed, the object is now built from within its
|
||||||
|
container, so that caches can be created and queries avoided.
|
||||||
|
|
||||||
* SoObjects/SOGo/NSArray+Utilities.m ([NSArray
|
* SoObjects/SOGo/NSArray+Utilities.m ([NSArray
|
||||||
-asPointersOfObjects]): new method that transforms an NSArray into
|
-asPointersOfObjects]): new method that transforms an NSArray into
|
||||||
an array of ptr**;
|
an array of ptr**;
|
||||||
|
|
|
@ -25,25 +25,24 @@
|
||||||
#import <SOGo/SOGoObject.h>
|
#import <SOGo/SOGoObject.h>
|
||||||
|
|
||||||
@class NSArray;
|
@class NSArray;
|
||||||
|
@class NSCalendarDate;
|
||||||
@class NSException;
|
@class NSException;
|
||||||
@class NSString;
|
@class NSString;
|
||||||
|
@class SOGoGCSFolder;
|
||||||
|
|
||||||
@interface SOGoContentObject : SOGoObject
|
@interface SOGoContentObject : SOGoObject
|
||||||
{
|
{
|
||||||
NSString *ocsPath;
|
|
||||||
NSDictionary *record;
|
|
||||||
BOOL isNew;
|
BOOL isNew;
|
||||||
|
NSString *content;
|
||||||
|
unsigned int version;
|
||||||
|
NSCalendarDate *creationDate;
|
||||||
|
NSCalendarDate *lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* accessors */
|
+ (SOGoContentObject *) objectWithRecord: (NSDictionary *) objectRecord
|
||||||
|
inContainer: (SOGoGCSFolder *) newContainer;
|
||||||
- (void) setOCSPath: (NSString *) _path;
|
- (id) initWithRecord: (NSDictionary *) objectRecord
|
||||||
- (NSString *) ocsPath;
|
inContainer: (id) newContainer;
|
||||||
|
|
||||||
/* folder */
|
|
||||||
|
|
||||||
- (NSString *) ocsPathOfContainer;
|
|
||||||
- (GCSFolder *) ocsFolder;
|
|
||||||
|
|
||||||
/* content */
|
/* content */
|
||||||
|
|
||||||
|
@ -57,6 +56,9 @@
|
||||||
/* etag support */
|
/* etag support */
|
||||||
|
|
||||||
- (id) davEntityTag;
|
- (id) davEntityTag;
|
||||||
|
- (NSString *) davCreationDate;
|
||||||
|
- (NSString *) davLastModified;
|
||||||
|
- (NSString *) davContentLength;
|
||||||
|
|
||||||
/* message type */
|
/* message type */
|
||||||
|
|
||||||
|
|
|
@ -41,17 +41,64 @@
|
||||||
|
|
||||||
@implementation SOGoContentObject
|
@implementation SOGoContentObject
|
||||||
|
|
||||||
|
+ (SOGoContentObject *) objectWithRecord: (NSDictionary *) objectRecord
|
||||||
|
inContainer: (SOGoGCSFolder *) newContainer
|
||||||
|
{
|
||||||
|
SOGoContentObject *newObject;
|
||||||
|
|
||||||
|
newObject = [[self alloc] initWithRecord: objectRecord
|
||||||
|
inContainer: newContainer];
|
||||||
|
[newObject autorelease];
|
||||||
|
|
||||||
|
return newObject;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: check superclass version
|
// TODO: check superclass version
|
||||||
|
|
||||||
- (id) initWithName: (NSString *) newName
|
- (id) init
|
||||||
inContainer: (id) newContainer
|
|
||||||
{
|
{
|
||||||
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
|
isNew = YES;
|
||||||
|
content = nil;
|
||||||
|
version = 0;
|
||||||
|
lastModified = nil;
|
||||||
|
creationDate = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void) _setRecord: (NSDictionary *) objectRecord
|
||||||
|
{
|
||||||
|
NSString *newContent;
|
||||||
|
int intValue;
|
||||||
|
|
||||||
|
newContent = [objectRecord objectForKey: @"c_content"];
|
||||||
|
if (newContent)
|
||||||
|
{
|
||||||
|
isNew = NO;
|
||||||
|
ASSIGN (content, newContent);
|
||||||
|
version = [[objectRecord objectForKey: @"c_version"] unsignedIntValue];
|
||||||
|
intValue = [[objectRecord objectForKey: @"c_creationdate"] intValue];
|
||||||
|
ASSIGN (creationDate,
|
||||||
|
[NSCalendarDate dateWithTimeIntervalSince1970: intValue]);
|
||||||
|
intValue = [[objectRecord objectForKey: @"c_lastmodified"] intValue];
|
||||||
|
ASSIGN (lastModified,
|
||||||
|
[NSCalendarDate dateWithTimeIntervalSince1970: intValue]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithRecord: (NSDictionary *) objectRecord
|
||||||
|
inContainer: (id) newContainer
|
||||||
|
{
|
||||||
|
NSString *newName;
|
||||||
|
|
||||||
|
newName = [objectRecord objectForKey: @"c_name"];
|
||||||
if ((self = [super initWithName: newName inContainer: newContainer]))
|
if ((self = [super initWithName: newName inContainer: newContainer]))
|
||||||
{
|
{
|
||||||
ocsPath = nil;
|
[self _setRecord: objectRecord];
|
||||||
record = [[self ocsFolder] recordOfEntryWithName: newName];
|
|
||||||
[record retain];
|
|
||||||
isNew = (!record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -59,8 +106,9 @@
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[record release];
|
[content release];
|
||||||
[ocsPath release];
|
[creationDate release];
|
||||||
|
[lastModified release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,54 +119,6 @@
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setOCSPath: (NSString *) newOCSPath
|
|
||||||
{
|
|
||||||
if (![ocsPath isEqualToString: newOCSPath])
|
|
||||||
{
|
|
||||||
if (ocsPath)
|
|
||||||
[self warnWithFormat:@"GCS path is already set! '%@'", newOCSPath];
|
|
||||||
|
|
||||||
ASSIGNCOPY (ocsPath, newOCSPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) ocsPath
|
|
||||||
{
|
|
||||||
NSMutableString *newOCSPath;
|
|
||||||
|
|
||||||
if (!ocsPath)
|
|
||||||
{
|
|
||||||
newOCSPath = [NSMutableString new];
|
|
||||||
[newOCSPath appendString: [self ocsPathOfContainer]];
|
|
||||||
if ([newOCSPath length] > 0)
|
|
||||||
{
|
|
||||||
if (![newOCSPath hasSuffix:@"/"])
|
|
||||||
[newOCSPath appendString: @"/"];
|
|
||||||
[newOCSPath appendString: nameInContainer];
|
|
||||||
ocsPath = newOCSPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ocsPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) ocsPathOfContainer
|
|
||||||
{
|
|
||||||
NSString *ocsPathOfContainer;
|
|
||||||
|
|
||||||
if ([container respondsToSelector: @selector (ocsPath)])
|
|
||||||
ocsPathOfContainer = [container ocsPath];
|
|
||||||
else
|
|
||||||
ocsPathOfContainer = nil;
|
|
||||||
|
|
||||||
return ocsPathOfContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (GCSFolder *) ocsFolder
|
|
||||||
{
|
|
||||||
return [container ocsFolder];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* content */
|
/* content */
|
||||||
|
|
||||||
- (BOOL) isNew
|
- (BOOL) isNew
|
||||||
|
@ -128,31 +128,32 @@
|
||||||
|
|
||||||
- (NSString *) contentAsString
|
- (NSString *) contentAsString
|
||||||
{
|
{
|
||||||
return [record objectForKey: @"c_content"];
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSException *) saveContentString: (NSString *) newContent
|
- (NSException *) saveContentString: (NSString *) newContent
|
||||||
baseVersion: (unsigned int) newBaseVersion
|
baseVersion: (unsigned int) newVersion
|
||||||
{
|
{
|
||||||
/* Note: "iCal multifolder saves" are implemented in the apt subclass! */
|
/* Note: "iCal multifolder saves" are implemented in the apt subclass! */
|
||||||
GCSFolder *folder;
|
GCSFolder *folder;
|
||||||
NSException *ex;
|
NSException *ex;
|
||||||
NSMutableDictionary *newRecord;
|
NSCalendarDate *now;
|
||||||
|
|
||||||
ex = nil;
|
ex = nil;
|
||||||
|
|
||||||
if (record)
|
now = [NSCalendarDate calendarDate];
|
||||||
newRecord = [NSMutableDictionary dictionaryWithDictionary: record];
|
if (!content)
|
||||||
else
|
ASSIGN (creationDate, now);
|
||||||
newRecord = [NSMutableDictionary dictionary];
|
ASSIGN (lastModified, now);
|
||||||
[newRecord setObject: newContent forKey: @"c_content"];
|
ASSIGN (content, newContent);
|
||||||
ASSIGN (record, newRecord);
|
version = newVersion;
|
||||||
|
|
||||||
folder = [container ocsFolder];
|
folder = [container ocsFolder];
|
||||||
if (folder)
|
if (folder)
|
||||||
{
|
{
|
||||||
ex = [folder writeContent: newContent toName: nameInContainer
|
ex = [folder writeContent: newContent
|
||||||
baseVersion: newBaseVersion];
|
toName: nameInContainer
|
||||||
|
baseVersion: newVersion];
|
||||||
if (ex)
|
if (ex)
|
||||||
[self errorWithFormat:@"write failed: %@", ex];
|
[self errorWithFormat:@"write failed: %@", ex];
|
||||||
}
|
}
|
||||||
|
@ -175,7 +176,7 @@
|
||||||
|
|
||||||
// TODO: add precondition check? (or add DELETEAction?)
|
// TODO: add precondition check? (or add DELETEAction?)
|
||||||
|
|
||||||
if ((folder = [self ocsFolder]) == nil) {
|
if ((folder = [container ocsFolder]) == nil) {
|
||||||
[self errorWithFormat:@"Did not find folder of content object."];
|
[self errorWithFormat:@"Did not find folder of content object."];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +239,6 @@
|
||||||
|
|
||||||
/* kinda dangerous */
|
/* kinda dangerous */
|
||||||
ASSIGNCOPY(nameInContainer, tmp);
|
ASSIGNCOPY(nameInContainer, tmp);
|
||||||
ASSIGN(ocsPath, nil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* determine base version from etag in if-match header */
|
/* determine base version from etag in if-match header */
|
||||||
|
@ -296,53 +296,22 @@
|
||||||
|
|
||||||
- (id) davEntityTag
|
- (id) davEntityTag
|
||||||
{
|
{
|
||||||
// TODO: cache tag in ivar? => if you do, remember to flush after PUT
|
return [NSString stringWithFormat: @"\"gcs%.8d\"", version];
|
||||||
GCSFolder *folder;
|
|
||||||
char buf[64];
|
|
||||||
NSString *entityTag;
|
|
||||||
NSNumber *versionValue;
|
|
||||||
|
|
||||||
folder = [self ocsFolder];
|
|
||||||
if (folder)
|
|
||||||
{
|
|
||||||
versionValue = [record objectForKey: @"c_version"];
|
|
||||||
sprintf (buf, "\"gcs%08d\"", [versionValue unsignedIntValue]);
|
|
||||||
entityTag = [NSString stringWithCString: buf];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[self errorWithFormat:@"Did not find folder of content object."];
|
|
||||||
entityTag = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entityTag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WebDAV */
|
/* WebDAV */
|
||||||
- (NSString *) davCreationDate
|
- (NSString *) davCreationDate
|
||||||
{
|
{
|
||||||
NSCalendarDate *date;
|
return [creationDate rfc822DateString];
|
||||||
|
|
||||||
date = [record objectForKey: @"c_creationdate"];
|
|
||||||
|
|
||||||
return [date rfc822DateString];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) davLastModified
|
- (NSString *) davLastModified
|
||||||
{
|
{
|
||||||
NSCalendarDate *date;
|
return [lastModified rfc822DateString];
|
||||||
|
|
||||||
date = [record objectForKey: @"c_lastmodified"];
|
|
||||||
|
|
||||||
return [date rfc822DateString];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) davContentLength
|
- (NSString *) davContentLength
|
||||||
{
|
{
|
||||||
NSString *content;
|
|
||||||
|
|
||||||
content = [record objectForKey: @"c_content"];
|
|
||||||
|
|
||||||
return [NSString stringWithFormat: @"%u",
|
return [NSString stringWithFormat: @"%u",
|
||||||
[content lengthOfBytesUsingEncoding: NSUTF8StringEncoding]];
|
[content lengthOfBytesUsingEncoding: NSUTF8StringEncoding]];
|
||||||
}
|
}
|
||||||
|
@ -441,13 +410,4 @@
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* description */
|
|
||||||
|
|
||||||
- (void) appendAttributesToDescription: (NSMutableString *) _ms
|
|
||||||
{
|
|
||||||
[super appendAttributesToDescription:_ms];
|
|
||||||
|
|
||||||
[_ms appendFormat:@" ocs=%@", [self ocsPath]];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end /* SOGoContentObject */
|
@end /* SOGoContentObject */
|
||||||
|
|
Loading…
Reference in New Issue