From: helge Date: Thu, 17 Feb 2005 14:38:14 +0000 (+0000) Subject: eliminated SOGoLogic X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d32b9a3ff9c3096b99be10500ba7430c90e79878;p=scalable-opengroupware.org eliminated SOGoLogic git-svn-id: http://svn.opengroupware.org/SOGo/trunk@577 d1b88da0-ebda-0310-925b-ed51d893ca5b --- diff --git a/SOGo/GNUmakefile b/SOGo/GNUmakefile index a655820d..42d2186e 100644 --- a/SOGo/GNUmakefile +++ b/SOGo/GNUmakefile @@ -1,4 +1,4 @@ -# $Id$ +# GNUstep makefile include $(GNUSTEP_MAKEFILES)/common.make diff --git a/SOGo/Protocols/iCalHTTP/SOGoICalFileFetch.m b/SOGo/Protocols/iCalHTTP/SOGoICalFileFetch.m index 17012fd3..2750764e 100644 --- a/SOGo/Protocols/iCalHTTP/SOGoICalFileFetch.m +++ b/SOGo/Protocols/iCalHTTP/SOGoICalFileFetch.m @@ -29,7 +29,7 @@ #include "SOGoICalHTTPHandler.h" #include -#include +#include #include "common.h" @implementation SOGoICalFileFetch diff --git a/SOGo/Protocols/iCalHTTP/SOGoICalFilePublish.m b/SOGo/Protocols/iCalHTTP/SOGoICalFilePublish.m index 42af8f06..9be217e9 100644 --- a/SOGo/Protocols/iCalHTTP/SOGoICalFilePublish.m +++ b/SOGo/Protocols/iCalHTTP/SOGoICalFilePublish.m @@ -30,7 +30,7 @@ #include "SOGoICalHTTPHandler.h" #include #include -#include +#include #include #include #include diff --git a/SOGo/SoObjects/Appointments/ChangeLog b/SOGo/SoObjects/Appointments/ChangeLog index a930ec03..07d3f48d 100644 --- a/SOGo/SoObjects/Appointments/ChangeLog +++ b/SOGo/SoObjects/Appointments/ChangeLog @@ -1,3 +1,7 @@ +2005-02-17 Helge Hess + + * fixed for removal of SOGoLogic (v0.9.26) + 2005-02-06 Helge Hess * SOGoAppointmentObject.m, SOGoAppointmentFolder.m: added proper diff --git a/SOGo/SoObjects/Appointments/GNUmakefile b/SOGo/SoObjects/Appointments/GNUmakefile index 5ff6acc3..c4709e5d 100644 --- a/SOGo/SoObjects/Appointments/GNUmakefile +++ b/SOGo/SoObjects/Appointments/GNUmakefile @@ -1,4 +1,4 @@ -# $Id: GNUmakefile,v 1.3 2004/04/06 13:01:10 helge Exp $ +# GNUstep makefile include ../common.make diff --git a/SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m b/SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m index 4c71f256..6a20cf0c 100644 --- a/SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 SKYRIX Software AG + Copyright (C) 2004-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -18,11 +18,11 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "SOGoAppointmentFolder.h" #include -#include +#include +#include #include #include #include diff --git a/SOGo/SoObjects/Appointments/SOGoAppointmentObject.m b/SOGo/SoObjects/Appointments/SOGoAppointmentObject.m index d182a0c1..90492304 100644 --- a/SOGo/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SOGo/SoObjects/Appointments/SOGoAppointmentObject.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 SKYRIX Software AG + Copyright (C) 2004-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -18,10 +18,10 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "SOGoAppointmentObject.h" -#include +#include +#include #include #include #include "common.h" diff --git a/SOGo/SoObjects/Appointments/Version b/SOGo/SoObjects/Appointments/Version index 688e0a02..00badea1 100644 --- a/SOGo/SoObjects/Appointments/Version +++ b/SOGo/SoObjects/Appointments/Version @@ -1,6 +1,7 @@ # Version file -SUBMINOR_VERSION:=25 +SUBMINOR_VERSION:=26 +# v0.9.26 requires libSOGo v0.9.30 # v0.9.19 requires NGiCal v4.5.36 # v0.9.13 requires libSOGo v0.9.26 diff --git a/SOGo/SoObjects/Appointments/common.h b/SOGo/SoObjects/Appointments/common.h index 88fc5806..acd6f20f 100644 --- a/SOGo/SoObjects/Appointments/common.h +++ b/SOGo/SoObjects/Appointments/common.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2004 SKYRIX Software AG + Copyright (C) 2002-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #import @@ -30,6 +29,3 @@ #include #include #include - -#include - diff --git a/SOGo/SoObjects/Contacts/SOGoContactFolder.m b/SOGo/SoObjects/Contacts/SOGoContactFolder.m index 7c7d6b58..1d62fac3 100644 --- a/SOGo/SoObjects/Contacts/SOGoContactFolder.m +++ b/SOGo/SoObjects/Contacts/SOGoContactFolder.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 SKYRIX Software AG + Copyright (C) 2004-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -18,11 +18,10 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include "SOGoContactFolder.h" #include -#include +#include #include #include #include "common.h" diff --git a/SOGo/SoObjects/Contacts/common.h b/SOGo/SoObjects/Contacts/common.h index 88fc5806..e213fd75 100644 --- a/SOGo/SoObjects/Contacts/common.h +++ b/SOGo/SoObjects/Contacts/common.h @@ -31,5 +31,3 @@ #include #include -#include - diff --git a/SOGo/SoObjects/Mailer/SOGoMailAccounts.m b/SOGo/SoObjects/Mailer/SOGoMailAccounts.m index 6c9e7c0d..c31717ad 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailAccounts.m +++ b/SOGo/SoObjects/Mailer/SOGoMailAccounts.m @@ -22,7 +22,7 @@ #include "SOGoMailAccounts.h" #include "common.h" #include -#include +#include @implementation SOGoMailAccounts diff --git a/SOGo/SoObjects/Mailer/common.h b/SOGo/SoObjects/Mailer/common.h index 42bb4ab6..bf5ab285 100644 --- a/SOGo/SoObjects/Mailer/common.h +++ b/SOGo/SoObjects/Mailer/common.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2004 SKYRIX Software AG + Copyright (C) 2002-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #import #import @@ -32,6 +31,4 @@ #include #include -#include - #include diff --git a/SOGo/SoObjects/SOGo/AgenorUserManager.h b/SOGo/SoObjects/SOGo/AgenorUserManager.h new file mode 100644 index 00000000..363c30fa --- /dev/null +++ b/SOGo/SoObjects/SOGo/AgenorUserManager.h @@ -0,0 +1,51 @@ +/* + 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. +*/ + +#ifndef __AgenorUserManager_H_ +#define __AgenorUserManager_H_ + +#import + +@class SOGoLRUCache; + +@interface AgenorUserManager : NSObject +{ + SOGoLRUCache *cnCache; + SOGoLRUCache *serverCache; + SOGoLRUCache *uidCache; + SOGoLRUCache *emailCache; +} + ++ (id)sharedUserManager; + +- (NSString *)getUIDForEmail:(NSString *)_email; +- (NSString *)getEmailForUID:(NSString *)_uid; + +/* i.e. BUTTO Hercule, CETE Lyon/DI/ET/TEST */ +- (NSString *)getCNForUID:(NSString *)_uid; +/* i.e. hercule.butto@amelie-ida01.melanie2.i2 */ +- (NSString *)getIMAPAccountStringForUID:(NSString *)_uid; +/* i.e. amelie-ida01.melanie2.i2 */ +- (NSString *)getServerForUID:(NSString *)_uid; + +@end + +#endif /* __AgenorUserManager_H_ */ diff --git a/SOGo/SoObjects/SOGo/AgenorUserManager.m b/SOGo/SoObjects/SOGo/AgenorUserManager.m new file mode 100644 index 00000000..f44dfdea --- /dev/null +++ b/SOGo/SoObjects/SOGo/AgenorUserManager.m @@ -0,0 +1,509 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + 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$ + + +#include "AgenorUserManager.h" +#include +#include +#include "SOGoLRUCache.h" + +@interface AgenorUserManager (PrivateAPI) +- (NGLdapConnection *)ldapConnection; + +- (void)_cacheCN:(NSString *)_cn forUID:(NSString *)_uid; +- (NSString *)_cachedCNForUID:(NSString *)_uid; +- (void)_cacheServer:(NSString *)_server forUID:(NSString *)_uid; +- (NSString *)_cachedServerForUID:(NSString *)_uid; +- (void)_cacheEmail:(NSString *)_email forUID:(NSString *)_uid; +- (NSString *)_cachedEmailForUID:(NSString *)_uid; +- (void)_cacheUID:(NSString *)_uid forEmail:(NSString *)_email; +- (NSString *)_cachedUIDForEmail:(NSString *)_email; + +@end + + +@implementation AgenorUserManager + +static BOOL debugOn = NO; +static BOOL useLDAP = NO; +static NSString *ldapHost = nil; +static NSString *ldapBaseDN = nil; + ++ (void)initialize { + static BOOL didInit = NO; + NSUserDefaults *ud; + + if(didInit) + return; + didInit = YES; + ud = [NSUserDefaults standardUserDefaults]; + debugOn = [ud boolForKey:@"SOGoUserManagerDebugEnabled"]; + useLDAP = [ud boolForKey:@"SOGoUserManagerUsesLDAP"]; + if(useLDAP) { + ldapHost = [[ud stringForKey:@"SOGoLDAPHost"] retain]; + ldapBaseDN = [[ud stringForKey:@"SOGoLDAPBaseDN"] retain]; + } +} + ++ (id)sharedUserManager { + static id mgr = nil; + if(mgr == nil) { + mgr = [[self alloc] init]; + } + return mgr; +} + +- (id)init { + self = [super init]; + if(self) { + self->serverCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->cnCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->uidCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + self->emailCache = [[SOGoLRUCache alloc] initWithCacheSize:10000]; + } + return self; +} + +- (void)dealloc { + [self->serverCache release]; + [self->cnCache release]; + [self->uidCache release]; + [self->emailCache release]; + [super dealloc]; +} + +- (NGLdapConnection *)ldapConnection { + static NGLdapConnection *ldapConnection = nil; + if(!ldapConnection) { + ldapConnection = [[NGLdapConnection alloc] initWithHostName:ldapHost]; +#if 0 + [ldapConnection setUseCache:YES]; +#endif + } + return ldapConnection; +} + + +/* private cache helpers */ + +- (void)_cacheCN:(NSString *)_cn forUID:(NSString *)_uid { + [self->cnCache addObject:_cn forKey:_uid]; +} + +- (NSString *)_cachedCNForUID:(NSString *)_uid { + return [self->cnCache objectForKey:_uid]; +} + +- (void)_cacheServer:(NSString *)_server forUID:(NSString *)_uid { + [self->serverCache addObject:_server forKey:_uid]; +} + +- (NSString *)_cachedServerForUID:(NSString *)_uid { + return [self->serverCache objectForKey:_uid]; +} + +- (void)_cacheEmail:(NSString *)_email forUID:(NSString *)_uid { + [self->emailCache addObject:_email forKey:_uid]; +} + +- (NSString *)_cachedEmailForUID:(NSString *)_uid { + return [self->emailCache objectForKey:_uid]; +} + +- (void)_cacheUID:(NSString *)_uid forEmail:(NSString *)_email { + [self->uidCache addObject:_uid forKey:_email]; +} + +- (NSString *)_cachedUIDForEmail:(NSString *)_email { + return [self->uidCache objectForKey:_email]; +} + + +/* uid <-> email mapping */ + +/* + UPDATE: the email excerpt below has been marked by Maxime as being + wrong. This algorithm can not be expected to work, thus + the mapping has been replaced with an LDAP query. + + --- snip --- + The uid field is in bijection this the email adress : + this field can be construct from the email. Email are uniques. + + So, we can use email adresse from identifier. + The field is made like this : + _ if the email is equipement.gouv.fr then the login + is the part before the @ + for example : fisrtName.lastName + _ if the email is not equipement.gouv.fr then the login + is the full email adress where @ is change to . (dot) + for example : fisrtName.lastName.subDomain.domain.tld + --- snap --- + + NOTE: mapping email -> uid is easy, but can also generate uid's not known + to the system (i.e. for private addressbook entries, obvious). + The reverse mapping can work _only_ if "firstName.lastname." is + guaranteed, because the second dot would be mapped to '@'. This + is probably error prone. + Only LDAP fetches would guarantee correctness in both cases. +*/ + +- (NSString *)getUIDForEmail:(NSString *)_email { + if(useLDAP) { + static NSArray *uidAttrs = nil; + NGLdapConnection *conn; + EOQualifier *q; + NSEnumerator *resultEnum; + NGLdapEntry *entry; + NGLdapAttribute *uidAttr; + NSString *uid; + + if(!uidAttrs) { + uidAttrs = [[NSArray alloc] initWithObjects:@"uid", nil]; + } + + if((uid = [self _cachedUIDForEmail:_email])) + return uid; + + q = [EOQualifier qualifierWithQualifierFormat:@"mail = %@", _email]; + + conn = [self ldapConnection]; + resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN + qualifier:q + attributes:uidAttrs]; + entry = [resultEnum nextObject]; + if(!entry) { + if(debugOn) { + [self logWithFormat:@"%s Didn't find LDAP entry for email '%@'!", + __PRETTY_FUNCTION__, + _email]; + } + return nil; + } + uidAttr = [entry attributeWithName:@"uid"]; + if (!uidAttr) + return nil; /* can happen, not unlikely */ + uid = [uidAttr stringValueAtIndex:0]; + [self _cacheUID:uid forEmail:_email]; + return uid; + } + else { + NSRange r; + NSString *domain; + + if(!_email || [_email length] == 0) + return nil; + + r = [_email rangeOfString:@"@"]; + if(r.length == 0) + return nil; + domain = [_email substringFromIndex:NSMaxRange(r)]; + if(![domain isEqualToString:@"equipement.gouv.fr"]) + return _email; + return [_email substringToIndex:r.location]; + } +} + +- (NSString *)getEmailForUID:(NSString *)_uid { + if(useLDAP) { + static NSArray *emailAttrs = nil; + NGLdapConnection *conn; + EOQualifier *q; + NSEnumerator *resultEnum; + NGLdapEntry *entry; + NGLdapAttribute *emailAttr; + NSString *email; + + if(!emailAttrs) { + emailAttrs = [[NSArray alloc] initWithObjects:@"mineqMelmailEmission", nil]; + } + + if((email = [self _cachedEmailForUID:_uid])) + return email; + + q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid]; + + conn = [self ldapConnection]; + resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN + qualifier:q + attributes:emailAttrs]; + entry = [resultEnum nextObject]; + if(!entry) { + if(debugOn) { + [self logWithFormat:@"%s Didn't find LDAP entry for uid '%@'!", + __PRETTY_FUNCTION__, + _uid]; + } + return nil; + } + emailAttr = [entry attributeWithName:@"mineqMelmailEmission"]; + if (!emailAttr) { + return nil; /* shit happens */ + } + else { + unsigned count; + + email = nil; + count = [emailAttr count]; +#if 0 + if (count > 1) { + unsigned i; + + /* in case there are multiple email addresses, select the first + which doesn't have '@equipement.gouv.fr' in it */ + for (i = 0; i < count; i++) { + NSString *candidate; + + candidate = [emailAttr stringValueAtIndex:i]; + if (![candidate hasSuffix:@"@equipement.gouv.fr"]) { + email = candidate; + break; + } + } + } +#endif + if (email == nil && count > 0) { + email = [emailAttr stringValueAtIndex:0]; + } + [self _cacheEmail:email forUID:_uid]; + return email; + } + } + else { + NSRange r; + + if(!_uid || [_uid length] == 0) + return nil; + r = [_uid rangeOfString:@"@"]; + if(r.length > 0) + return _uid; + return [NSString stringWithFormat:@"%@@equipement.gouv.fr", _uid]; + } +} + + +/* CN */ + +- (NSString *)getCNForUID:(NSString *)_uid { + if(useLDAP) { + static NSArray *cnAttrs = nil; + NGLdapConnection *conn; + EOQualifier *q; + NSEnumerator *resultEnum; + NGLdapEntry *entry; + NGLdapAttribute *cnAttr; + NSString *cn; + + if(!cnAttrs) { + cnAttrs = [[NSArray alloc] initWithObjects:@"cn", nil]; + } + + if((cn = [self _cachedCNForUID:_uid])) + return cn; + + q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid]; + + conn = [self ldapConnection]; + resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN + qualifier:q + attributes:cnAttrs]; + entry = [resultEnum nextObject]; + if(!entry) { + if(debugOn) { + [self logWithFormat:@"%s Didn't find LDAP entry for uid '%@'!", + __PRETTY_FUNCTION__, + _uid]; + } + return nil; + } + cnAttr = [entry attributeWithName:@"cn"]; + if(!cnAttr && debugOn) { + [self logWithFormat:@"%s LDAP entry for uid '%@' has no common name?", + __PRETTY_FUNCTION__, + _uid]; + return nil; /* nothing we can do about it */ + } + cn = [cnAttr stringValueAtIndex:0]; + [self _cacheCN:cn forUID:_uid]; + return cn; + } + else { + NSString *s; + NSRange r; + + s = _uid; + if ([s length] < 10) + return s; + + // TODO: algorithm might be inappropriate, depends on the actual UID + r = [s rangeOfString:@"."]; + if (r.length == 0) + return s; + + return [s substringToIndex:r.location]; + } +} + + +/* Servers, IMAP */ + +- (NSString *)getIMAPAccountStringForUID:(NSString *)_uid { + NSString *server; + + server = [self getServerForUID:_uid]; + if(!server) + return nil; + return [NSString stringWithFormat:@"%@@%@", _uid, server]; +} + +- (NSString *)getServerForUID:(NSString *)_uid { + /* + First of all : for a particular user IMAP and SMTP are served on the same + host. + + The name of the machine is determined by applying a regex on every values of + the mineqMelRoutage LDAP attribute. + The regex is : .*%.*@(.*\.melanie2\.i2$) + It extracts the substring that follows '@', ends with 'melanie2', on + adresses which have a '%' before the '@' + + Example: helge.hesse%opengroupware.org@servername1.melanie2.i2 + -> servername1.melanie2.i2 + + If only one server name is found by applying the regex on every value of the + attribute, then this name is the IMAP/SMTP server for that user. + Note that this is the case when we got a unique (well formed) value for the + attribute. + If the regex finds more than one servername when applied to the differents + values, then the IMAP/SMTP server name is to be found in the + mineqMelServeurPrincipal attribute of the user. + */ + if(useLDAP) { + static NSArray *attrs = nil; + NGLdapConnection *conn; + EOQualifier *q; + NSEnumerator *resultEnum; + NGLdapEntry *entry; + NGLdapAttribute *attr; + NSMutableArray *serverCandidates; + NSString *server; + + if(!attrs) { + attrs = [[NSArray alloc] initWithObjects:@"mineqMelRoutage", + @"mineqMelServeurPrincipal", + nil]; + } + + if((server = [self _cachedServerForUID:_uid])) + return server; + + q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid]; + + conn = [self ldapConnection]; + resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN + qualifier:q + attributes:attrs]; + /* we just expect one entry, thus drop the rest */ + entry = [resultEnum nextObject]; + if(!entry) { + if(debugOn) { + NSLog(@"%s Didn't find LDAP entry for uid '%@'!", + __PRETTY_FUNCTION__, + _uid); + } + return nil; + } + attr = [entry attributeWithName:@"mineqMelRoutage"]; + if(attr) { + unsigned i, count; + + count = [attr count]; + serverCandidates = [NSMutableArray arrayWithCapacity:count]; + for(i = 0; i < count; i++) { + NSRange r; + NSString *route; + + route = [attr stringValueAtIndex:i]; + r = [route rangeOfString:@".melanie2.i2" options:NSBackwardsSearch]; + if(r.length > 0) { + unsigned length; + + /* be clever */ + length = [route length]; + r = NSMakeRange(0, length - r.length); + r = [route rangeOfString:@"@" options:NSBackwardsSearch range:r]; + if(r.length > 0) { + unsigned start; + NSRange serverNameRange; + + start = NSMaxRange(r); + serverNameRange = NSMakeRange(start, length - start); + r = NSMakeRange(0, length - start); + r = [route rangeOfString:@"%" options:NSBackwardsSearch range:r]; + if(r.length > 0) { + NSString *serverName; + + serverName = [route substringWithRange:serverNameRange]; + [serverCandidates addObject:serverName]; + } + } + } + } + } + else { + if(debugOn) { + NSLog(@"%s LDAP entry for uid '%@' has no mineqMelRoutage entry?", + __PRETTY_FUNCTION__, + _uid); + } + serverCandidates = nil; + } + if([serverCandidates count] == 1) { + server = [serverCandidates objectAtIndex:0]; + } + + /* last resort */ + if(!server) { + attr = [entry attributeWithName:@"mineqMelServeurPrincipal"]; + if([attr count] > 0) + server = [attr stringValueAtIndex:0]; + } + + if(!server) { + if(debugOn) { + NSLog(@"%s no chance of getting at server info for user '%@', " + @"tried everything. Sorry.", + __PRETTY_FUNCTION__, + _uid); + } + return nil; + } + + [self _cacheServer:server forUID:_uid]; + return server; + } + else { + return @"mail.opengroupware.org"; + } +} + +@end diff --git a/SOGo/SoObjects/SOGo/ChangeLog b/SOGo/SoObjects/SOGo/ChangeLog index e675c154..ef68cad0 100644 --- a/SOGo/SoObjects/SOGo/ChangeLog +++ b/SOGo/SoObjects/SOGo/ChangeLog @@ -1,3 +1,8 @@ +2005-02-17 Helge Hess + + * moved in code from libSOGoLogic (unnecessarily a separate library) + (v0.9.30) + 2005-02-10 Helge Hess * SOGoObject.m: fixed a warning on MacOSX (v0.9.29) diff --git a/SOGo/SoObjects/SOGo/GNUmakefile b/SOGo/SoObjects/SOGo/GNUmakefile index 29a0cb5c..7f92ca8f 100644 --- a/SOGo/SoObjects/SOGo/GNUmakefile +++ b/SOGo/SoObjects/SOGo/GNUmakefile @@ -19,6 +19,11 @@ libSOGo_HEADER_FILES = \ SOGoGroupsFolder.h \ SOGoGroupFolder.h \ SOGoCustomGroupFolder.h \ + \ + SOGoAppointment.h \ + AgenorUserManager.h \ + SOGoLRUCache.h \ + NSString+iCal.h libSOGo_OBJC_FILES = \ SOGoObject.m \ @@ -28,6 +33,11 @@ libSOGo_OBJC_FILES = \ SOGoGroupsFolder.m \ SOGoGroupFolder.m \ SOGoCustomGroupFolder.m \ + \ + SOGoAppointment.m \ + SOGoAppointmentICalRenderer.m \ + SOGoLRUCache.m \ + AgenorUserManager.m \ -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/library.make diff --git a/SOGo/SoObjects/SOGo/NSString+iCal.h b/SOGo/SoObjects/SOGo/NSString+iCal.h new file mode 100644 index 00000000..f8d29ccf --- /dev/null +++ b/SOGo/SoObjects/SOGo/NSString+iCal.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + 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$ + + +#ifndef __NSString_iCal_H_ +#define __NSString_iCal_H_ + +// DEPRECATED + +#import +#include + +#endif /* __NSString_iCal_H_ */ diff --git a/SOGo/SoObjects/SOGo/SOGoAppointment.h b/SOGo/SoObjects/SOGo/SOGoAppointment.h new file mode 100644 index 00000000..dfdd731f --- /dev/null +++ b/SOGo/SoObjects/SOGo/SOGoAppointment.h @@ -0,0 +1,134 @@ +/* + 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$ + +#ifndef __SOGoAppointment_H_ +#define __SOGoAppointment_H_ + +#import +#import + +/* + SOGoAppointment + + Wrapper around the iCalendar content of appointments stored in the + OGoContentStore. +*/ + +@class NSString, NSArray, NSCalendarDate, NGCalendarDateRange; +@class iCalPerson, iCalEvent, iCalRecurrenceRule; + +@interface SOGoAppointment : NSObject +{ + id calendar; + iCalEvent *event; + id participants; +} + +- (id)initWithICalString:(NSString *)_iCal; + +- (void)setUid:(NSString *)_value; +- (NSString *)uid; + +- (void)setSummary:(NSString *)_value; +- (NSString *)summary; + +- (void)setLocation:(NSString *)_value; +- (NSString *)location; +- (BOOL)hasLocation; + +- (void)setComment:(NSString *)_value; +- (NSString *)comment; +- (BOOL)hasComment; + +- (void)setPriority:(NSString *)_value; +- (NSString *)priority; +- (BOOL)hasPriority; + +- (void)setCategories:(NSArray *)_value; +- (NSArray *)categories; +- (BOOL)hasCategories; + +- (void)setStatus:(NSString *)_value; +- (NSString *)status; + +- (void)setStartDate:(NSCalendarDate *)_date; +- (NSCalendarDate *)startDate; + +- (void)setEndDate:(NSCalendarDate *)_date; +- (NSCalendarDate *)endDate; +- (BOOL)hasEndDate; + +- (BOOL)hasDuration; +- (void)setDuration:(NSTimeInterval)_duration; +- (NSTimeInterval)duration; + +- (void)setOrganizer:(iCalPerson *)_organizer; +- (iCalPerson *)organizer; + +- (void)setAccessClass:(NSString *)_value; +- (NSString *)accessClass; +- (BOOL)isPublic; + +- (void)setTransparency:(NSString *)_value; +- (NSString *)transparency; +- (BOOL)isTransparent; + +- (void)removeAllAttendees; +- (void)addToAttendees:(iCalPerson *)_person; +- (void)appendAttendees:(NSArray *)_persons; +- (void)setAttendees:(NSArray *)_persons; +- (NSArray *)attendees; + +/* attendees -> role != NON-PART */ +- (NSArray *)participants; +/* attendees -> role == NON-PART */ +- (NSArray *)resources; + +/* simplified recurrence API */ +- (void)setRecurrenceRule:(iCalRecurrenceRule *)_rrule; +- (iCalRecurrenceRule *)recurrenceRule; +- (BOOL)hasRecurrenceRule; + +- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r; + +/* iCal generation */ + +- (NSString *)iCalString; +- (NSString *)vEventString; + +/* raw entity objects */ + +- (id)calendar; +- (id)event; + +/* checking */ + +- (BOOL)isOrganizer:(id)_email; +- (BOOL)isParticipant:(id)_email; + +/* searching */ + +- (iCalPerson *)findParticipantWithEmail:(id)_email; + +@end + +#endif /* __SOGoAppointment_H_ */ diff --git a/SOGo/SoObjects/SOGo/SOGoAppointment.m b/SOGo/SoObjects/SOGo/SOGoAppointment.m new file mode 100644 index 00000000..1d5fbb19 --- /dev/null +++ b/SOGo/SoObjects/SOGo/SOGoAppointment.m @@ -0,0 +1,442 @@ +/* + 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. +*/ + +#include "SOGoAppointment.h" +#include +#include +#include +#include "SOGoAppointmentICalRenderer.h" +#include "common.h" + +@interface SOGoAppointment (PrivateAPI) +- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons; +@end + +@implementation SOGoAppointment + +static id parser = nil; +static SaxObjectDecoder *sax = nil; +static NGLogger *logger = nil; + ++ (void)initialize { + NGLoggerManager *lm; + SaxXMLReaderFactory *factory; + static BOOL didInit = NO; + + if (didInit) return; + didInit = YES; + + lm = [NGLoggerManager defaultLoggerManager]; + logger = [lm loggerForClass:self]; + + factory = [SaxXMLReaderFactory standardXMLReaderFactory]; + parser = [[factory createXMLReaderForMimeType:@"text/calendar"] + retain]; + if (parser == nil) + [logger fatalWithFormat:@"did not find a parser for text/calendar!"]; + sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"]; + if (sax == nil) + [logger fatalWithFormat:@"could not create the iCal SAX handler!"]; + + [parser setContentHandler:sax]; + [parser setErrorHandler:sax]; +} + +- (id)initWithICalRootObject:(id)_root { + if ((self = [super init])) { +#if 0 + [self logWithFormat:@"root is: %@", root]; +#endif + + if ([_root isKindOfClass:[iCalEvent class]]) { + self->event = [_root retain]; + } + else if ([_root isKindOfClass:[NSDictionary class]]) { + /* multiple vevents in the calendar */ + [self errorWithFormat: + @"(%s): tried to initialize with multiple records: %@", + __PRETTY_FUNCTION__, _root]; + [self release]; + return nil; + } + else { + self->calendar = [_root retain]; + self->event = [[[self->calendar events] lastObject] retain]; + } + } + return self; +} +- (id)initWithICalString:(NSString *)_iCal { + id root; + + if ([_iCal length] == 0) { + [self errorWithFormat:@"tried to init SOGoAppointment without iCal"]; + [self release]; + return nil; + } + if (parser == nil || sax == nil) { + [self errorWithFormat:@"iCal parser not properly set up!"]; + [self release]; + return nil; + } + + if ([_iCal length] > 0) { + [parser parseFromSource:_iCal]; + root = [[sax rootObject] retain]; /* retain to keep it around */ + [sax reset]; + } + else + root = nil; + + self = [self initWithICalRootObject:root]; + [root release]; + return self; +} + +- (void)dealloc { + [self->calendar release]; + [self->event release]; + [super dealloc]; +} + +/* accessors */ + +- (id)calendar { + return self->calendar; +} + +- (id)event { + return self->event; +} + +- (NSString *)iCalString { + return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer] + stringForAppointment:self]; +} +- (NSString *)vEventString { + return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer] + vEventStringForAppointment:self]; +} + +/* forwarded methods */ + +- (void)setUid:(NSString *)_value { + [self->event setUid:_value]; +} +- (NSString *)uid { + return [self->event uid]; +} + +- (void)setSummary:(NSString *)_value { + [self->event setSummary:_value]; +} +- (NSString *)summary { + return [self->event summary]; +} + +- (void)setLocation:(NSString *)_value { + [self->event setLocation:_value]; +} +- (NSString *)location { + return [self->event location]; +} +- (BOOL)hasLocation { + if (![[self location] isNotNull]) + return NO; + return [[self location] length] > 0 ? YES : NO; +} + +- (void)setComment:(NSString *)_value { + if([_value length] == 0) + _value = nil; + [self->event setComment:_value]; +} +- (NSString *)comment { + return [self->event comment]; +} +- (BOOL)hasComment { + NSString *s = [self comment]; + if(!s || [s length] == 0) + return NO; + return YES; +} + +- (void)setPriority:(NSString *)_value { + [self->event setPriority:_value]; +} +- (NSString *)priority { + return [self->event priority]; +} +- (BOOL)hasPriority { + NSString *prio = [self priority]; + NSRange r; + + if(!prio) + return NO; + + r = [prio rangeOfString:@";"]; + if(r.length > 0) { + prio = [prio substringToIndex:r.location]; + } + return [prio isEqualToString:@"0"] ? NO : YES; +} + +- (void)setCategories:(NSArray *)_value { + NSString *catString; + + if(!_value || [_value count] == 0) { + [self->event setCategories:nil]; + return; + } + _value = [_value sortedArrayUsingSelector:@selector(compareAscending:)]; + catString = [_value componentsJoinedByString:@","]; + [self->event setCategories:catString]; + [catString release]; +} +- (NSArray *)categories { + NSString *catString; + NSArray *cats; + NSRange r; + + catString = [self->event categories]; + if (![catString isNotNull]) + return [NSArray array]; + + r = [[catString stringValue] rangeOfString:@";"]; + if(r.length > 0) { + catString = [catString substringToIndex:r.location]; + } + cats = [catString componentsSeparatedByString:@","]; + return cats; +} +- (BOOL)hasCategories { + return [self->event categories] != nil ? YES : NO; +} + +- (void)setStatus:(NSString *)_value { + [self->event setStatus:_value]; +} +- (NSString *)status { + return [self->event status]; +} + +- (void)setStartDate:(NSCalendarDate *)_date { + [self->event setStartDate:_date]; +} +- (NSCalendarDate *)startDate { + return [self->event startDate]; +} + +- (void)setEndDate:(NSCalendarDate *)_date { + [self->event setEndDate:_date]; +} +- (NSCalendarDate *)endDate { + return [self->event endDate]; +} +- (BOOL)hasEndDate { + return [self->event hasEndDate]; +} + +- (void)setDuration:(NSTimeInterval)_duration { + // TODO + [self warnWithFormat:@"could not apply duration!"]; +} +- (BOOL)hasDuration { + return [self->event hasDuration]; +} +- (NSTimeInterval)duration { + return [self->event durationAsTimeInterval]; +} + +- (void)setAccessClass:(NSString *)_value { + [self->event setAccessClass:_value]; +} +- (NSString *)accessClass { + NSString *s; + + s = [self->event accessClass]; + if(!s) + s = @"PUBLIC"; /* default for agenor */ + return s; +} +- (BOOL)isPublic { + return [[self accessClass] isEqualToString:@"PUBLIC"]; +} + +- (void)setTransparency:(NSString *)_value { + [self->event setTransparency:_value]; +} +- (NSString *)transparency { + return [self->event transparency]; +} +- (BOOL)isTransparent { + return [[self transparency] isEqualToString:@"TRANSPARENT"]; +} + +- (void)setOrganizer:(iCalPerson *)_organizer { + [self->event setOrganizer:_organizer]; +} +- (iCalPerson *)organizer { + return [self->event organizer]; +} + +- (void)removeAllAttendees { + [self setAttendees:nil]; +} +- (void)addToAttendees:(iCalPerson *)_person { + [self->event addToAttendees:_person]; +} +- (void)appendAttendees:(NSArray *)_persons { + unsigned i, count; + + count = [_persons count]; + for (i = 0; i < count; i++) + [self addToAttendees:[_persons objectAtIndex:i]]; +} +- (void)setAttendees:(NSArray *)_persons { + [self->event removeAllAttendees]; + if ([_persons count] > 0) + [self appendAttendees:_persons]; +} +- (NSArray *)attendees { + return [self->event attendees]; +} + +- (NSArray *)participants { + if (self->participants != nil) + return self->participants; + + self->participants = [[self _filteredAttendeesThinkingOfPersons:YES] retain]; + return self->participants; +} +- (BOOL)hasParticipants { + return [[self participants] count] != 0; +} + +- (NSArray *)resources { + return [self _filteredAttendeesThinkingOfPersons:NO]; +} + +- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons { + NSArray *list; + NSMutableArray *filtered; + unsigned i, count; + + list = [self attendees]; + count = [list count]; + filtered = [NSMutableArray arrayWithCapacity:count]; + for (i = 0; i < count; i++) { + iCalPerson *p; + NSString *role; + + p = [list objectAtIndex:i]; + role = [p role]; + if (_persons) { + if (role == nil || ![role hasPrefix:@"NON-PART"]) + [filtered addObject:p]; + } + else { + if ([role hasPrefix:@"NON-PART"]) + [filtered addObject:p]; + } + } + return filtered; +} + +- (BOOL)isOrganizer:(id)_email { + return [[[self organizer] rfc822Email] isEqualToString:_email]; +} + +- (BOOL)isParticipant:(id)_email { + NSArray *partEmails; + + partEmails = [[self participants] valueForKey:@"rfc822Email"]; + return [partEmails containsObject:_email]; +} + +- (iCalPerson *)findParticipantWithEmail:(id)_email { + NSArray *ps; + unsigned i, count; + + ps = [self participants]; + count = [ps count]; + + for (i = 0; i < count; i++) { + iCalPerson *p; + + p = [ps objectAtIndex:i]; + if ([[p rfc822Email] isEqualToString:_email]) + return p; + } + return nil; /* not found */ +} + + +/* + NOTE: this is not the same API as used by NGiCal! + SOGo/OGo cannot deal with the complete NGiCal API properly, although + SOGo COULD do so in the future +*/ +- (void)setRecurrenceRule:(iCalRecurrenceRule *)_rrule { + [_rrule retain]; + [self->event removeAllRecurrenceRules]; + if (_rrule) + [self->event addToRecurrenceRules:_rrule]; + [_rrule release]; +} +- (iCalRecurrenceRule *)recurrenceRule { + if ([self->event hasRecurrenceRules]) + return [[self->event recurrenceRules] objectAtIndex:0]; + return nil; +} +- (BOOL)hasRecurrenceRule { + return [self recurrenceRule] != nil; +} + +- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r { + return [self->event recurrenceRangesWithinCalendarDateRange:_r]; +} + + +/* description */ + +- (void)appendAttributesToDescription:(NSMutableString *)_ms { + [_ms appendFormat:@" uid=%@", [self uid]]; + [_ms appendFormat:@" date=%@", [self startDate]]; +} + +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:64]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + [self appendAttributesToDescription:ms]; + [ms appendString:@">"]; + return ms; +} + +/* logging */ + +- (id)logger { + return logger; +} + +@end /* SOGoAppointment */ diff --git a/SOGo/SoObjects/SOGo/SOGoAppointmentICalRenderer.h b/SOGo/SoObjects/SOGo/SOGoAppointmentICalRenderer.h new file mode 100644 index 00000000..afdd2e6f --- /dev/null +++ b/SOGo/SoObjects/SOGo/SOGoAppointmentICalRenderer.h @@ -0,0 +1,46 @@ +/* + 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: SOGoAppointment.h 207 2004-08-14 15:37:04Z znek $ + +#ifndef __SOGoAppointmentICalRenderer_H_ +#define __SOGoAppointmentICalRenderer_H_ + +#import + +/* + SOGoAppointmentICalRenderer + + Transform an SOGoAppointment into an iCalendar formatted string. +*/ + +@class NSString; +@class SOGoAppointment; + +@interface SOGoAppointmentICalRenderer : NSObject + ++ (id)sharedAppointmentRenderer; + +- (NSString *)vEventStringForAppointment:(SOGoAppointment *)_apt; +- (NSString *)stringForAppointment:(SOGoAppointment *)_apt; + +@end + +#endif /* __SOGoAppointmentICalRenderer_H_ */ diff --git a/SOGo/SoObjects/SOGo/SOGoAppointmentICalRenderer.m b/SOGo/SoObjects/SOGo/SOGoAppointmentICalRenderer.m new file mode 100644 index 00000000..d0e53fdc --- /dev/null +++ b/SOGo/SoObjects/SOGo/SOGoAppointmentICalRenderer.m @@ -0,0 +1,250 @@ +/* + 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. +*/ + +#include "SOGoAppointmentICalRenderer.h" +#include "SOGoAppointment.h" +#include "NSString+iCal.h" +#include +#include "common.h" + +// TODO: the basic renderer should be part of NGiCal + +@interface NSDate(UsedPrivates) +- (NSString *)icalString; // declared in NGiCal +@end + +@implementation SOGoAppointmentICalRenderer + +static SOGoAppointmentICalRenderer *renderer = nil; + +/* assume length of 1K - reasonable ? */ +static unsigned DefaultICalStringCapacity = 1024; + ++ (id)sharedAppointmentRenderer { + if (renderer == nil) + renderer = [[self alloc] init]; + return renderer; +} + +/* renderer */ + +- (void)addPreambleForAppointment:(SOGoAppointment *)_apt + toString:(NSMutableString *)s +{ + iCalCalendar *calendar; + + calendar = [_apt calendar]; + + [s appendString:@"BEGIN:VCALENDAR\r\nMETHOD:REQUEST\r\n"]; + + [s appendString:@"PRODID:"]; + [s appendString:[calendar isNotNull] ? [calendar prodId] : @"SOGo/0.9"]; + [s appendString:@"\r\n"]; + + [s appendString:@"VERSION:"]; + [s appendString:[calendar isNotNull] ? [calendar version] : @"2.0"]; + [s appendString:@"\r\n"]; +} +- (void)addPostambleForAppointment:(SOGoAppointment *)_apt + toString:(NSMutableString *)s +{ + [s appendString:@"END:VCALENDAR\r\n"]; +} + +- (void)addOrganizer:(iCalPerson *)p toString:(NSMutableString *)s { + NSString *x; + + if (![p isNotNull]) return; + + [s appendString:@"ORGANIZER;CN=\""]; + if ((x = [p cn])) + [s appendString:[x iCalDQUOTESafeString]]; + + [s appendString:@"\""]; + if ((x = [p email])) { + [s appendString:@":"]; /* sic! */ + [s appendString:[x iCalSafeString]]; + } + [s appendString:@"\r\n"]; +} + +- (void)addAttendees:(NSArray *)persons toString:(NSMutableString *)s { + unsigned i, count; + iCalPerson *p; + + count = [persons count]; + for (i = 0; i < count; i++) { + NSString *x; + + p = [persons objectAtIndex:i]; + [s appendString:@"ATTENDEE;"]; + + if ((x = [p role])) { + [s appendString:@"ROLE="]; + [s appendString:[x iCalSafeString]]; + [s appendString:@";"]; + } + + if ((x = [p partStat])) { + if ([p participationStatus] != iCalPersonPartStatNeedsAction) { + [s appendString:@"PARTSTAT="]; + [s appendString:[x iCalSafeString]]; + [s appendString:@";"]; + } + } + + [s appendString:@"CN=\""]; + if ((x = [p cnWithoutQuotes])) { + [s appendString:[x iCalDQUOTESafeString]]; + } + [s appendString:@"\""]; + if ([(x = [p email]) isNotNull]) { + [s appendString:@":"]; /* sic! */ + [s appendString:[x iCalSafeString]]; + } + [s appendString:@"\r\n"]; + } +} + +- (void)addVEventForAppointment:(SOGoAppointment *)_apt + toString:(NSMutableString *)s +{ + iCalEvent *event; + + event = [_apt event]; + + [s appendString:@"BEGIN:VEVENT\r\n"]; + + [s appendString:@"SUMMARY:"]; + [s appendString:[[_apt summary] iCalSafeString]]; + [s appendString:@"\r\n"]; + if ([_apt hasLocation]) { + [s appendString:@"LOCATION:"]; + [s appendString:[[_apt location] iCalSafeString]]; + [s appendString:@"\r\n"]; + } + [s appendString:@"UID:"]; + [s appendString:[_apt uid]]; + [s appendString:@"\r\n"]; + + [s appendString:@"DTSTART:"]; + [s appendString:[[_apt startDate] icalString]]; + [s appendString:@"\r\n"]; + + if ([_apt hasEndDate]) { + [s appendString:@"DTEND:"]; + [s appendString:[[_apt endDate] icalString]]; + [s appendString:@"\r\n"]; + } + if ([_apt hasDuration]) { + [s appendString:@"DURATION:"]; + [s appendString:[event duration]]; + [s appendString:@"\r\n"]; + } + if([_apt hasPriority]) { + [s appendString:@"PRIORITY:"]; + [s appendString:[_apt priority]]; + [s appendString:@"\r\n"]; + } + if([_apt hasCategories]) { + NSString *catString; + + catString = [[_apt categories] componentsJoinedByString:@","]; + [s appendString:@"CATEGORIES:"]; + [s appendString:catString]; + [s appendString:@"\r\n"]; + } + if([_apt hasComment]) { + [s appendString:@"DESCRIPTION:"]; /* this is what iCal.app does */ + [s appendString:[[_apt comment] iCalSafeString]]; + [s appendString:@"\r\n"]; + } + + [s appendString:@"STATUS:"]; + [s appendString:[_apt status]]; + [s appendString:@"\r\n"]; + + [s appendString:@"TRANSP:"]; + [s appendString:[_apt transparency]]; + [s appendString:@"\r\n"]; + + [s appendString:@"CLASS:"]; + [s appendString:[_apt accessClass]]; + [s appendString:@"\r\n"]; + + /* recurrence rules */ + if ([_apt hasRecurrenceRule]) { + [s appendString:@"RRULE:"]; + [s appendString:[[_apt recurrenceRule] iCalRepresentation]]; + [s appendString:@"\r\n"]; + } + + [self addOrganizer:[_apt organizer] toString:s]; + [self addAttendees:[_apt attendees] toString:s]; + + /* postamble */ + [s appendString:@"END:VEVENT\r\n"]; +} + +- (BOOL)isValidAppointment:(SOGoAppointment *)_apt { + if (![_apt isNotNull]) + return NO; + + if ([[_apt uid] length] == 0) { + [self warnWithFormat:@"got apt without uid, rejecting iCal generation: %@", + _apt]; + return NO; + } + if ([[[_apt startDate] icalString] length] == 0) { + [self warnWithFormat:@"got apt without start date, " + @"rejecting iCal generation: %@", + _apt]; + return NO; + } + + return YES; +} + +- (NSString *)vEventStringForAppointment:(SOGoAppointment *)_apt { + NSMutableString *s; + + if (![self isValidAppointment:_apt]) + return nil; + + s = [NSMutableString stringWithCapacity:DefaultICalStringCapacity]; + [self addVEventForAppointment:_apt toString:s]; + return s; +} + +- (NSString *)stringForAppointment:(SOGoAppointment *)_apt { + NSMutableString *s; + + if (![self isValidAppointment:_apt]) + return nil; + + s = [NSMutableString stringWithCapacity:DefaultICalStringCapacity]; + [self addPreambleForAppointment:_apt toString:s]; + [self addVEventForAppointment:_apt toString:s]; + [self addPostambleForAppointment:_apt toString:s]; + return s; +} + +@end /* SOGoAppointmentICalRenderer */ diff --git a/SOGo/SoObjects/SOGo/SOGoLRUCache.h b/SOGo/SoObjects/SOGo/SOGoLRUCache.h new file mode 100644 index 00000000..1d29a504 --- /dev/null +++ b/SOGo/SoObjects/SOGo/SOGoLRUCache.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + 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$ + + +#ifndef __SOGoLRUCache_H_ +#define __SOGoLRUCache_H_ + + +#import + + +@interface SOGoLRUCache : NSObject +{ + unsigned size; + NSMutableDictionary *entries; +} + +- (id)initWithCacheSize:(unsigned)_size; + +- (void)addObject:(id)_obj forKey:(id)_key; +- (id)objectForKey:(id)_key; + +@end + +#endif /* __SOGoLRUCache_H_ */ diff --git a/SOGo/SoObjects/SOGo/SOGoLRUCache.m b/SOGo/SoObjects/SOGo/SOGoLRUCache.m new file mode 100644 index 00000000..dd11e77c --- /dev/null +++ b/SOGo/SoObjects/SOGo/SOGoLRUCache.m @@ -0,0 +1,114 @@ +/* + Copyright (C) 2000-2004 SKYRIX Software AG + + This file is part of OGo + + 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$ + + +#import "SOGoLRUCache.h" +#import "common.h" + +@interface SOGoLRUCacheItem : NSObject +{ + id object; + unsigned useCount; +} + +- (id)initWithObject:(id)_obj; +- (id)object; + +- (unsigned)useCount; + +@end + +@implementation SOGoLRUCacheItem + +- (id)initWithObject:(id)_obj { + self = [super init]; + if(self) { + ASSIGN(self->object, _obj); + self->useCount = 1; + } + return self; +} + +- (id)object { + self->useCount++; + return self->object; +} + +- (unsigned)useCount { + return self->useCount; +} + +@end + +@implementation SOGoLRUCache + +- (id)initWithCacheSize:(unsigned)_size { + self = [super init]; + if(self) { + self->size = _size; + self->entries = [[NSMutableDictionary alloc] initWithCapacity:_size]; + } + return self; +} + +- (void)dealloc { + [self->entries release]; + [super dealloc]; +} + +- (void)addObject:(id)_obj forKey:(id)_key { + SOGoLRUCacheItem *item; + + NSAssert(_obj, @"Attempt to insert nil object!"); + + if([self->entries count] >= self->size) { + /* need to find minimum and get rid of it */ + NSEnumerator *keyEnum; + SOGoLRUCacheItem *item; + id key, leastUsedItemKey; + unsigned minimumUseCount = INT_MAX; + + keyEnum = [self->entries keyEnumerator]; + while((key = [keyEnum nextObject])) { + item = [self->entries objectForKey:key]; + if([item useCount] < minimumUseCount) { + minimumUseCount = [item useCount]; + leastUsedItemKey = key; + } + } + [self->entries removeObjectForKey:leastUsedItemKey]; + } + item = [[SOGoLRUCacheItem alloc] initWithObject:_obj]; + [self->entries setObject:item forKey:_key]; + [item release]; +} + +- (id)objectForKey:(id)_key { + SOGoLRUCacheItem *item; + + item = [self->entries objectForKey:_key]; + if(!item) + return nil; + return [item object]; +} + +@end diff --git a/SOGo/SoObjects/SOGo/Version b/SOGo/SoObjects/SOGo/Version index cbb9c17f..ddd701e9 100644 --- a/SOGo/SoObjects/SOGo/Version +++ b/SOGo/SoObjects/SOGo/Version @@ -1,5 +1,5 @@ # version file -SUBMINOR_VERSION:=29 +SUBMINOR_VERSION:=30 # v0.9.26 requires libOGoContentStore v0.9.13 diff --git a/SOGo/SoObjects/Sieve/common.h b/SOGo/SoObjects/Sieve/common.h index a33aeedc..bf5ab285 100644 --- a/SOGo/SoObjects/Sieve/common.h +++ b/SOGo/SoObjects/Sieve/common.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2004 SKYRIX Software AG + Copyright (C) 2002-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id: common.h 335 2004-09-29 23:24:45Z helge $ #import #import @@ -32,6 +31,4 @@ #include #include -#include - #include diff --git a/SOGo/UI/Anais/AnaisAttendeeSelector.m b/SOGo/UI/Anais/AnaisAttendeeSelector.m index a1a3694a..be53632a 100644 --- a/SOGo/UI/Anais/AnaisAttendeeSelector.m +++ b/SOGo/UI/Anais/AnaisAttendeeSelector.m @@ -66,7 +66,7 @@ @end #include -#include +#include #include #include #include diff --git a/SOGo/UI/Contacts/UIxContactsSelectionView.m b/SOGo/UI/Contacts/UIxContactsSelectionView.m index 4d0fd86b..ff13bca4 100644 --- a/SOGo/UI/Contacts/UIxContactsSelectionView.m +++ b/SOGo/UI/Contacts/UIxContactsSelectionView.m @@ -38,7 +38,7 @@ @end #include "common.h" -#include +#include @implementation UIxContactsSelectionView diff --git a/SOGo/UI/Scheduler/ChangeLog b/SOGo/UI/Scheduler/ChangeLog index 138177d6..cb478a5c 100644 --- a/SOGo/UI/Scheduler/ChangeLog +++ b/SOGo/UI/Scheduler/ChangeLog @@ -1,8 +1,10 @@ -2005-02-15 Marcus Mueller +2005-02-17 Helge Hess + + * fixed for removal of SOGoLogic (v0.9.114) - * v0.9.113 +2005-02-15 Marcus Mueller - * UIxCalView.m: removed dead code + * UIxCalView.m: removed dead code (v0.9.113) 2005-02-12 Marcus Mueller diff --git a/SOGo/UI/Scheduler/SOGoAppointment+UIx.h b/SOGo/UI/Scheduler/SOGoAppointment+UIx.h index d8792e72..dbbcaeca 100644 --- a/SOGo/UI/Scheduler/SOGoAppointment+UIx.h +++ b/SOGo/UI/Scheduler/SOGoAppointment+UIx.h @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2004 SKYRIX Software AG + Copyright (C) 2000-2005 SKYRIX Software AG - This file is part of OGo + 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 @@ -18,15 +18,11 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ - #ifndef __SOGoAppointment_UIx_H_ #define __SOGoAppointment_UIx_H_ - -#include - +#include @interface SOGoAppointment (UIx) - (NSString *)priorityLabelKey; diff --git a/SOGo/UI/Scheduler/UIxAppointmentEditor.m b/SOGo/UI/Scheduler/UIxAppointmentEditor.m index 402e1389..52b336fe 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentEditor.m +++ b/SOGo/UI/Scheduler/UIxAppointmentEditor.m @@ -86,10 +86,10 @@ #include #include #include -#include +#include +#include #include #include -#include #include "iCalPerson+UIx.h" #include "UIxComponent+Agenor.h" diff --git a/SOGo/UI/Scheduler/UIxAppointmentPrintview.m b/SOGo/UI/Scheduler/UIxAppointmentPrintview.m index 9d4862f1..914674d4 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentPrintview.m +++ b/SOGo/UI/Scheduler/UIxAppointmentPrintview.m @@ -31,7 +31,7 @@ #include "common.h" #include -#include +#include #include "UIxComponent+Agenor.h" @implementation UIxAppointmentPrintview diff --git a/SOGo/UI/Scheduler/UIxAppointmentView.m b/SOGo/UI/Scheduler/UIxAppointmentView.m index 9346d774..4811c9d5 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentView.m +++ b/SOGo/UI/Scheduler/UIxAppointmentView.m @@ -1,8 +1,27 @@ -// $Id$ +/* + 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. +*/ #include "UIxAppointmentView.h" #include -#include +#include #include #include #include "UIxComponent+Agenor.h" diff --git a/SOGo/UI/Scheduler/UIxCalDayListview.m b/SOGo/UI/Scheduler/UIxCalDayListview.m index 8d8848f8..691cc3e6 100644 --- a/SOGo/UI/Scheduler/UIxCalDayListview.m +++ b/SOGo/UI/Scheduler/UIxCalDayListview.m @@ -32,7 +32,7 @@ @end #include "common.h" -#include +#include @implementation UIxCalDayListview diff --git a/SOGo/UI/Scheduler/UIxCalView.m b/SOGo/UI/Scheduler/UIxCalView.m index 516fa638..efaa78fa 100644 --- a/SOGo/UI/Scheduler/UIxCalView.m +++ b/SOGo/UI/Scheduler/UIxCalView.m @@ -6,8 +6,6 @@ #include "SoObjects/Appointments/SOGoAppointmentFolder.h" #include #include -#include -#include #include #include "UIxComponent+Agenor.h" diff --git a/SOGo/UI/Scheduler/UIxCalWeekChartview.m b/SOGo/UI/Scheduler/UIxCalWeekChartview.m index f74e4f63..da79ddbe 100644 --- a/SOGo/UI/Scheduler/UIxCalWeekChartview.m +++ b/SOGo/UI/Scheduler/UIxCalWeekChartview.m @@ -35,7 +35,6 @@ #include "common.h" #include -#include #include // MIN, MAX #include diff --git a/SOGo/UI/Scheduler/UIxCalWeekListview.m b/SOGo/UI/Scheduler/UIxCalWeekListview.m index e4839aaf..043130a5 100644 --- a/SOGo/UI/Scheduler/UIxCalWeekListview.m +++ b/SOGo/UI/Scheduler/UIxCalWeekListview.m @@ -35,7 +35,7 @@ #include "common.h" #include -#include +#include #include @implementation UIxCalWeekListview diff --git a/SOGo/UI/Scheduler/UIxComponent+Agenor.m b/SOGo/UI/Scheduler/UIxComponent+Agenor.m index 2240b5df..e5831d67 100644 --- a/SOGo/UI/Scheduler/UIxComponent+Agenor.m +++ b/SOGo/UI/Scheduler/UIxComponent+Agenor.m @@ -1,7 +1,7 @@ /* - Copyright (C) 2000-2004 SKYRIX Software AG + Copyright (C) 2000-2005 SKYRIX Software AG - This file is part of OGo + 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 @@ -18,27 +18,25 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ - #include "UIxComponent+Agenor.h" -#include +#include #include "common.h" -@implementation UIxComponent (Agenor) +@implementation UIxComponent(Agenor) - (NSString *)emailForUser { - NSString *uid; + NSString *uid; - uid = [[self user] login]; - return [[AgenorUserManager sharedUserManager] getEmailForUID:uid]; + uid = [[self user] login]; + return [[AgenorUserManager sharedUserManager] getEmailForUID:uid]; } - (NSString *)cnForUser { - NSString *uid; + NSString *uid; - uid = [[self user] login]; - return [[AgenorUserManager sharedUserManager] getCNForUID:uid]; + uid = [[self user] login]; + return [[AgenorUserManager sharedUserManager] getCNForUID:uid]; } -@end +@end /* UIxComponent(Agenor) */ diff --git a/SOGo/UI/Scheduler/Version b/SOGo/UI/Scheduler/Version index 537a34c6..91eb058c 100644 --- a/SOGo/UI/Scheduler/Version +++ b/SOGo/UI/Scheduler/Version @@ -1,7 +1,8 @@ -# $Id$ +# Version file -SUBMINOR_VERSION:=112 +SUBMINOR_VERSION:=113 +# v0.9.113 requires libSOGo v0.9.30 # v0.9.112 requires SOGoLogic v0.9.12 # v0.9.107 requires WOExtensions v4.5.21 # v0.9.105 requires NGObjWeb v4.5.102