diff --git a/ChangeLog b/ChangeLog index 430420ead..d4396f499 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ 2008-06-13 Wolfgang Sourdeau + * SoObjects/SOGo/SOGoGCSFolder.m + ([-fetchContentStringsAndNamesOfAllObjects]): removed useless method. + ([SOGoGCSFolder + -lookupName:keyinContext:localContextacquire:acquire]): added new + overriden method, to fetch all the required metadata and content + for basic handling of SOGoContentObjects. + ([SOGoGCSFolder -fetchContentObjectNames]): prefetch and cache all + the metadata and content of children objects since this method is + used by the PROPFIND operation, which will likely require children + instantiation. + ([SOGoGCSFolder -objectClassForComponentName:componentName]): new + mandatory method for subclasses. + ([SOGoGCSFolder -objectClassForContent:content]): new mandator + method for subclasses. + ([SOGoGCSFolder + -lookupName:keyinContext:localContextacquire:acquire]): fetch and + cache the requested child object record. + * SoObjects/SOGo/SOGoObject.m ([SOGoObject -ownerInContext:localContext]): set a new ivar: activeUserIsOwner to reduce method calls. diff --git a/SoObjects/SOGo/SOGoGCSFolder.h b/SoObjects/SOGo/SOGoGCSFolder.h index c64f879ca..600345f45 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.h +++ b/SoObjects/SOGo/SOGoGCSFolder.h @@ -47,6 +47,7 @@ { NSString *ocsPath; GCSFolder *ocsFolder; + NSMutableDictionary *childRecords; NSMutableDictionary *aclCache; } @@ -69,8 +70,10 @@ - (void) deleteEntriesWithIds: (NSArray *) ids; +- (Class) objectClassForComponentName: (NSString *) componentName; +- (Class) objectClassForContent: (NSString *) content; + - (NSArray *) fetchContentObjectNames; -- (NSDictionary *) fetchContentStringsAndNamesOfAllObjects; /* folder type */ diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index 893f12ef0..728f39284 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -22,12 +22,13 @@ */ #import -#import +#import #import #import #import #import #import +#import #import #import @@ -65,6 +66,7 @@ static NSString *defaultUserID = @""; static BOOL sendFolderAdvisories = NO; +static NSArray *childRecordFields = nil; @implementation SOGoGCSFolder @@ -131,6 +133,13 @@ static BOOL sendFolderAdvisories = NO; ud = [NSUserDefaults standardUserDefaults]; sendFolderAdvisories = [ud boolForKey: @"SOGoFoldersSendEMailNotifications"]; + if (!childRecordFields) + { + childRecordFields = [NSArray arrayWithObjects: @"c_name", @"c_version", + @"c_creationdate", @"c_lastmodified", + @"c_component", @"c_content", nil]; + [childRecordFields retain]; + } } + (id) folderWithSubscriptionReference: (NSString *) reference @@ -172,6 +181,7 @@ static BOOL sendFolderAdvisories = NO; ocsPath = nil; ocsFolder = nil; aclCache = [NSMutableDictionary new]; + childRecords = [NSMutableDictionary new]; } return self; @@ -182,6 +192,7 @@ static BOOL sendFolderAdvisories = NO; [ocsFolder release]; [ocsPath release]; [aclCache release]; + [childRecords release]; [super dealloc]; } @@ -442,10 +453,10 @@ static BOOL sendFolderAdvisories = NO; - (NSArray *) fetchContentObjectNames { - NSArray *fields, *records; + NSArray *records, *names; - fields = [NSArray arrayWithObject: @"c_name"]; - records = [[self ocsFolder] fetchFields:fields matchingQualifier:nil]; + records = [[self ocsFolder] fetchFields: childRecordFields + matchingQualifier:nil]; if (![records isNotNull]) { [self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__]; @@ -454,24 +465,119 @@ static BOOL sendFolderAdvisories = NO; if ([records isKindOfClass: [NSException class]]) return records; - return [records objectsForKey: @"c_name"]; + [childRecords release]; + names = [records objectsForKey: @"c_name"]; + childRecords = [[NSMutableDictionary alloc] initWithObjects: records + forKeys: names]; + + return names; } -- (BOOL) nameExistsInFolder: (NSString *) objectName +- (NSDictionary *) _recordForObjectName: (NSString *) objectName { - NSArray *fields, *records; + NSArray *records; EOQualifier *qualifier; + NSDictionary *record; qualifier = [EOQualifier qualifierWithQualifierFormat: [NSString stringWithFormat: @"c_name='%@'", objectName]]; - fields = [NSArray arrayWithObject: @"c_name"]; - records = [[self ocsFolder] fetchFields: fields + records = [[self ocsFolder] fetchFields: childRecordFields matchingQualifier: qualifier]; - return (records - && ![records isKindOfClass:[NSException class]] - && [records count] > 0); + if (![records isKindOfClass: [NSException class]] + && [records count]) + record = [records objectAtIndex: 0]; + else + record = nil; + + return record; +} + +- (BOOL) nameExistsInFolder: (NSString *) objectName +{ + NSDictionary *record; + + record = [self _recordForObjectName: objectName]; + + return (record != nil); +} + +- (Class) objectClassForComponentName: (NSString *) componentName +{ + [self subclassResponsibility: _cmd]; + + return Nil; +} + +- (Class) objectClassForContent: (NSString *) content +{ + [self subclassResponsibility: _cmd]; + + return Nil; +} + +- (id) _createChildComponentWithRecord: (NSDictionary *) record +{ + Class klazz; + + klazz = [self objectClassForComponentName: + [record objectForKey: @"c_component"]]; + + return [klazz objectWithRecord: record inContainer: self]; +} + +- (id) _createChildComponentWithName: (NSString *) newName + andContent: (NSString *) newContent +{ + Class klazz; + NSDictionary *record; + unsigned int now; + NSNumber *nowNumber; + + klazz = [self objectClassForContent: newContent]; + now = [[NSCalendarDate calendarDate] timeIntervalSince1970]; + nowNumber = [NSNumber numberWithUnsignedInt: now]; + record = [NSDictionary dictionaryWithObjectsAndKeys: newName, @"c_name", + newContent, @"c_content", + nowNumber, @"c_creationdate", + nowNumber, @"c_lastmodified", nil]; + + return [klazz objectWithRecord: record inContainer: self]; +} + +- (id) lookupName: (NSString *) key + inContext: (WOContext *) localContext + acquire: (BOOL) acquire +{ + id obj; + NSDictionary *record; + WORequest *request; + + obj = [super lookupName: key + inContext: localContext + acquire: acquire]; + if (!obj) + { + record = [childRecords objectForKey: key]; + if (!record) + { + record = [self _recordForObjectName: key]; + if (record) + [childRecords setObject: record forKey: key]; + } + if (record) + obj = [self _createChildComponentWithRecord: record]; + else + { + request = [localContext request]; + if ([[request method] isEqualToString: @"PUT"]) + obj = [self _createChildComponentWithName: key + andContent:[request contentAsString]]; + } + } + + return obj; } - (void) deleteEntriesWithIds: (NSArray *) ids @@ -485,7 +591,8 @@ static BOOL sendFolderAdvisories = NO; { currentID = [ids objectAtIndex: count]; deleteObject = [self lookupName: currentID - inContext: context acquire: NO]; + inContext: context + acquire: NO]; if (![deleteObject isKindOfClass: [NSException class]]) { if ([deleteObject respondsToSelector: @selector (prepareDelete)]) @@ -495,20 +602,6 @@ static BOOL sendFolderAdvisories = NO; } } -- (NSDictionary *) fetchContentStringsAndNamesOfAllObjects -{ - NSDictionary *files; - - files = [[self ocsFolder] fetchContentsOfAllFiles]; - if (![files isNotNull]) - { - [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__]; - return nil; - } - - return files; -} - #warning this code should be cleaned up - (void) _subscribeUser: (SOGoUser *) subscribingUser reallyDo: (BOOL) reallyDo