]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@183 d1b88da0-ebda-0310-925b-ed51d...
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 11 Aug 2004 15:58:46 +0000 (15:58 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 11 Aug 2004 15:58:46 +0000 (15:58 +0000)
SOGo/SoObjects/Appointments/ChangeLog
SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m
SOGo/SoObjects/Appointments/SOGoGroupAppointmentFolder.m
SOGo/SoObjects/Appointments/Version

index 14a1ca0825bd5bd558cc05fbce7cecc322e2c84d..7141aa20c92b181ce65fd28ceec81608604bcfd2 100644 (file)
@@ -1,5 +1,9 @@
 2004-08-11  Helge Hess  <helge.hess@skyrix.com>
 
+       * SOGoGroupAppointmentFolder: can merge input folders, tracks conflicts
+         in 'conflicts' key of the record (should be displayed somehow in the
+         UI) (v0.9.3)
+
        * v0.9.2
 
        * SOGoAppointmentFolder.m, SOGoGroupAppointmentFolder: added 
index 4d3dd0058a682f72f539f08a09fc929291998219..be8734b4ee20df02fe9334e7b5fde2390c5d1504 100644 (file)
@@ -205,6 +205,7 @@ static NSTimeZone *MET = nil;
 - (NSArray *)fetchCoreInfosFrom:(NSCalendarDate *)_startDate
   to:(NSCalendarDate *)_endDate 
 {
+  /* this is the primary API */
   OCSFolder *folder;
   
   if ((folder = [self ocsFolder]) == nil) {
index 06b32b333820c936ff511c5a9d2cb8bc5b43d2e4..a3eaa57a62ea12cc08f738152813711f4ef1a991 100644 (file)
   return [[self container] valueForKey:@"uids"];
 }
 
+/* merging */
+
+- (BOOL)doesRecord:(NSDictionary *)_rec conflictWith:(NSDictionary *)_other {
+  if (_rec == _other) 
+    return NO;
+  if ([_rec isEqual:_other])
+    return NO;
+  
+  return YES;
+}
+
+- (NSDictionary *)_registerConflictingRecord:(NSDictionary *)_other
+  inRecord:(NSDictionary *)_record
+{
+  NSMutableArray *conflicts;
+  
+  if (_record == nil) return _other;
+  if (_other  == nil) return _record;
+  
+  if ((conflicts = [_record objectForKey:@"conflicts"]) == nil) {
+    NSMutableDictionary *md;
+    
+    md = [[_record copy] autorelease];
+    conflicts = [NSMutableArray arrayWithCapacity:4];
+    [md setObject:conflicts forKey:@"conflicts"];
+    _record = md;
+  }
+  [conflicts addObject:_other];
+  return _record;
+}
+
 /* functionality */
 
+- (NSArray *)fetchCoreInfosFrom:(NSCalendarDate *)_startDate
+  to:(NSCalendarDate *)_endDate
+  memberFolder:(id)_folder
+{
+  SOGoAppointmentFolder *aptFolder;
+  
+  if (![_folder isNotNull])
+    return nil;
+  
+  aptFolder = [_folder lookupName:@"Calendar" inContext:nil acquire:NO];
+  if (![aptFolder isNotNull]) {
+    [self logWithFormat:@"ERROR: member folder no 'Calendar': %@", _folder];
+    return nil;
+  }
+  
+  if (![aptFolder respondsToSelector:@selector(fetchCoreInfosFrom:to:)]) {
+    [self logWithFormat:@"ERROR: folder does not implemented required API: %@",
+           _folder];
+    return nil;
+  }
+  
+  return [aptFolder fetchCoreInfosFrom:_startDate to:_endDate];
+}
+
+- (NSArray *)fetchCoreInfosFrom:(NSCalendarDate *)_startDate
+  to:(NSCalendarDate *)_endDate
+  memberFolders:(NSArray *)_folders
+{
+  NSMutableArray *result;
+  NSMutableDictionary *uidToRecord;
+  unsigned i, count;
+  
+  if ((count = [_folders count]) == 0)
+    return [NSArray array];
+  if (count == 1) {
+    return [self fetchCoreInfosFrom:_startDate to:_endDate 
+                memberFolder:[_folders objectAtIndex:0]];
+  }
+  
+  uidToRecord = [NSMutableDictionary dictionaryWithCapacity:(7 * count)];
+  result      = [NSMutableArray arrayWithCapacity:(7 * count)];
+  for (i = 0; i < count; i++) {
+    id           results;
+    NSDictionary *record;
+    
+    results = [self fetchCoreInfosFrom:_startDate to:_endDate 
+                   memberFolder:[_folders objectAtIndex:i]];
+    if (![results isNotNull]) continue;
+
+    results = [results objectEnumerator];
+    while ((record = [results nextObject])) {
+      NSString     *uid;
+      NSDictionary *existingRecord;
+      
+      uid = [record objectForKey:@"uid"];
+      if (![uid isNotNull]) {
+       [self logWithFormat:@"WARNING: record without uid: %@", result];
+       [result addObject:record];
+       continue;
+      }
+      
+      if ((existingRecord = [uidToRecord objectForKey:uid]) == nil) {
+       /* record not yet in result set */
+       [uidToRecord setObject:record forKey:uid];
+       [result addObject:record];
+      }
+      else if ([self doesRecord:existingRecord conflictWith:record]) {
+       /* record already registered and it conflicts (diff values) */
+       NSDictionary *newRecord;
+       int idx;
+       
+       newRecord = [self _registerConflictingRecord:record 
+                         inRecord:existingRecord];
+       [uidToRecord setObject:newRecord forKey:uid];
+       
+       if ((idx = [result indexOfObject:existingRecord]) != NSNotFound)
+         [result replaceObjectAtIndex:idx withObject:newRecord];
+      }
+      else {
+       /* record already registered, but values in sync, nothing to do */
+      }
+    }
+  }
+  return result;
+}
+
 - (NSArray *)fetchCoreInfosFrom:(NSCalendarDate *)_startDate
   to:(NSCalendarDate *)_endDate
 {
-#warning TODO: implement aggregation based on the container
+  /* this is the main dispatcher method */
   NSArray *folders;
   
   if ((folders = [[self container] valueForKey:@"memberFolders"]) == nil) {
     return nil;
   }
   
-  return [NSArray array];
+  return [self fetchCoreInfosFrom:_startDate to:_endDate 
+              memberFolders:folders];
 }
 
 @end /* SOGoGroupAppointmentFolder */
index d277318d27b3d7b819dd0782e2b4cebe985dbebb..58d50ae77d3f66c8fbad9645666f8f90ab95d8e3 100644 (file)
@@ -1,3 +1,3 @@
 # $Id: Version,v 1.9 2004/05/19 14:30:45 helge Exp $
 
-SUBMINOR_VERSION:=2
+SUBMINOR_VERSION:=3