See ChangeLog

Monotone-Parent: 1e01e7055612c8aa2f2c0e9151035ef348604b8e
Monotone-Revision: ab8b4a7a66ffdb6688f466f2cc301caf1fc40a66

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2010-09-24T19:13:02
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Ludovic Marcotte
2010-09-24 19:13:02 +00:00
parent 38af9bc66b
commit 3d2f08f678
25 changed files with 1 additions and 1485 deletions
-1
View File
@@ -6,7 +6,6 @@ WOBUNDLE_NAME = Appointments
Appointments_PRINCIPAL_CLASS = SOGoAppointmentsProduct
# SOGoGroupAppointmentFolder.m
Appointments_OBJC_FILES = \
Product.m \
NSArray+Appointments.m \
@@ -1,52 +0,0 @@
/*
Copyright (C) 2004 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
// $Id: SOGoAppointmentFolder.h 137 2004-07-02 17:42:14Z helge $
#ifndef __Appointments_SOGoGroupAppointmentFolder_H__
#define __Appointments_SOGoGroupAppointmentFolder_H__
#include "SOGoAppointmentFolder.h"
/*
SOGoGroupAppointmentFolder
Parent object: an SOGoGroupFolder (or subclass)
Child objects: SOGoAppointmentObject
Note: this is only a subclass of SOGoAppointmentFolder to inherit all the
SOPE methods (it provides the same API). It is not an ocsFolder but
rather looks up the "child" folders for aggregation using regular SOPE
techniques.
=> hm, do we need "aspects" in SOPE? ;-)
Note: this class retains appointment folders looked up, so watch out for
reference cycles!
*/
@class NSMutableDictionary;
@interface SOGoGroupAppointmentFolder : SOGoAppointmentFolder
{
NSMutableDictionary *uidToFolder;
}
@end
#endif /* __Appointments_SOGoGroupAppointmentFolder_H__ */
@@ -1,254 +0,0 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h>
#import <NGObjWeb/SoSecurityManager.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGCards/iCalEntityObject.h>
#import <SOGo/SOGoGroupFolder.h>
#import <SOGo/SOGoPermissions.h>
#import "SOGoGroupAppointmentFolder.h"
@implementation SOGoGroupAppointmentFolder
+ (int)version {
return [super version] + 0 /* v1 */;
}
+ (void)initialize {
NSAssert2([super version] == 1,
@"invalid superclass (%@) version %i !",
NSStringFromClass([self superclass]), [super version]);
}
- (void)dealloc {
[self->uidToFolder release];
[super dealloc];
}
/* looking up shared objects */
- (SOGoGroupsFolder *)lookupGroupsFolder {
return [[self container] lookupGroupsFolder];
}
/* selection */
- (NSArray *)calendarUIDs {
return [[self container] valueForKey:@"uids"];
}
/* folders */
- (void)resetFolderCaches {
[self->uidToFolder release]; self->uidToFolder = nil;
}
- (SOGoAppointmentFolder *)folderForUID:(NSString *)_uid {
if (self->uidToFolder == nil) {
// TODO: can we trigger a fetch?
[self errorWithFormat:
@"called -folderForUID method before fetchCoreInfos .."];
return nil;
}
return [self->uidToFolder objectForKey:_uid];
}
/* 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 mutableCopy] autorelease];
conflicts = [NSMutableArray arrayWithCapacity:4];
[md setObject:conflicts forKey:@"conflicts"];
_record = md;
}
[conflicts addObject:_other];
return _record;
}
/* functionality */
- (SOGoAppointmentFolder *)calendarFolderForMemberFolder:(id)_folder {
SOGoAppointmentFolder *aptFolder;
if (![_folder isNotNull])
return nil;
aptFolder = [_folder lookupName:@"Calendar" inContext:nil acquire:NO];
if (![aptFolder isNotNull])
return nil;
if (![aptFolder respondsToSelector:@selector(fetchCoreInfosFrom:to:component:)]) {
[self errorWithFormat:@"folder does not implemented required API: %@",
_folder];
return nil;
}
return aptFolder;
}
/* overridden */
- (NSArray *) fetchFields: (NSArray *) _fields
from: (NSCalendarDate *) _startDate
to: (NSCalendarDate *) _endDate
component: (id) _component
{
NSArray *folders;
NSMutableArray *result;
NSMutableDictionary *uidToRecord;
unsigned i, count;
SoSecurityManager *securityManager;
securityManager = [SoSecurityManager sharedSecurityManager];
folders = [[self container] memberFolders];
[self resetFolderCaches];
if ((count = [folders count]) == 0)
return [NSArray array];
if (self->uidToFolder == nil)
self->uidToFolder = [[NSMutableDictionary alloc] initWithCapacity:7*count];
else
[self->uidToFolder removeAllObjects];
uidToRecord = [NSMutableDictionary dictionaryWithCapacity:(7 * count)];
result = [NSMutableArray arrayWithCapacity:(7 * count)];
for (i = 0; i < count; i++) {
SOGoAppointmentFolder *aptFolder;
id results;
NSDictionary *record;
aptFolder = [self calendarFolderForMemberFolder:
[folders objectAtIndex:i]];
if (![aptFolder isNotNull]) {
[self debugWithFormat:@"did not find a Calendar folder in folder: %@",
[folders objectAtIndex:i]];
continue;
}
if ([securityManager validatePermission: SoPerm_AccessContentsInformation
onObject: aptFolder
inContext: context]) {
[self debugWithFormat:@"no permission to read the content of calendar: %@",
[folders objectAtIndex:i]];
continue;
}
results = [aptFolder fetchFields: _fields
from: _startDate
to: _endDate
title: nil
component: _component];
if (![results isNotNull]) continue;
results = [results objectEnumerator];
while ((record = [results nextObject])) {
NSString *uid;
NSDictionary *existingRecord;
uid = [record objectForKey:@"uid"];
if (![uid isNotNull]) {
[self warnWithFormat:@"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];
[self->uidToFolder setObject:aptFolder forKey:uid];
}
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;
}
/* URL generation */
- (NSString *)baseURLForAptWithUID:(NSString *)_uid inContext:(id)_ctx {
/* Note: fetchCore must have been called before this works */
SOGoAppointmentFolder *folder;
if ([_uid length] == 0) {
[self errorWithFormat:@"got invalid UID."];
return nil;
}
if ((folder = [self folderForUID:_uid]) == nil) {
[self errorWithFormat:@"did not find a folder containing UID: '%@'",
_uid];
return nil;
}
if (![folder respondsToSelector:_cmd]) {
[self errorWithFormat:@"found folder cannot construct UID URLs: %@",
folder];
return nil;
}
[self debugWithFormat:@"found ID %@ in folder: %@", _uid, folder];
return [folder baseURLForAptWithUID:_uid inContext:_ctx];
}
@end /* SOGoGroupAppointmentFolder */