mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-21 14:43:31 +00:00
see ChangeLog
Monotone-Revision: 9054022ef1ca8aeba6e34842d27d9b94ce002b89 Monotone-Author: dev-unix.inverse.qc.ca Monotone-Date: 2006-06-15T19:34:10 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright (C) 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 __AgenorUserDefaults_H_
|
||||
#define __AgenorUserDefaults_H_
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
/*
|
||||
AgenorUserDefaults
|
||||
|
||||
An object with the same API like NSUserDefaults which retrieves profile
|
||||
information for users in the database.
|
||||
*/
|
||||
|
||||
@class NSString, NSURL, NSUserDefaults, NSArray, NSDictionary, NSData;
|
||||
@class NSCalendarDate, NSMutableDictionary;
|
||||
|
||||
@interface AgenorUserDefaults : NSObject
|
||||
{
|
||||
NSUserDefaults *parent;
|
||||
NSURL *url;
|
||||
NSString *uid;
|
||||
|
||||
NSArray *fieldNames;
|
||||
NSDictionary *attributes;
|
||||
NSMutableDictionary *values;
|
||||
NSCalendarDate *lastFetch;
|
||||
|
||||
struct {
|
||||
int modified:1;
|
||||
int isNew:1;
|
||||
int reserved:30;
|
||||
} defFlags;
|
||||
}
|
||||
|
||||
- (id)initWithTableURL:(NSURL *)_url uid:(NSString *)_uid;
|
||||
|
||||
/* value access */
|
||||
|
||||
- (void)setObject:(id)_value forKey:(NSString *)_key;
|
||||
- (id)objectForKey:(NSString *)_key;
|
||||
- (void)removeObjectForKey:(NSString *)_key;
|
||||
|
||||
/* typed accessors */
|
||||
|
||||
- (NSArray *)arrayForKey:(NSString *)_key;
|
||||
- (NSDictionary *)dictionaryForKey:(NSString *)_key;
|
||||
- (NSData *)dataForKey:(NSString *)_key;
|
||||
- (NSArray *)stringArrayForKey:(NSString *)_key;
|
||||
- (NSString *)stringForKey:(NSString *)_key;
|
||||
- (BOOL)boolForKey:(NSString *)_key;
|
||||
- (float)floatForKey:(NSString *)_key;
|
||||
- (int)integerForKey:(NSString *)_key;
|
||||
|
||||
- (void)setBool:(BOOL)value forKey:(NSString *)_key;
|
||||
- (void)setFloat:(float)value forKey:(NSString *)_key;
|
||||
- (void)setInteger:(int)value forKey:(NSString *)_key;
|
||||
|
||||
/* saving changes */
|
||||
|
||||
- (BOOL)synchronize;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __AgenorUserDefaults_H_ */
|
||||
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
Copyright (C) 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 "AgenorUserDefaults.h"
|
||||
#include <GDLContentStore/GCSChannelManager.h>
|
||||
#include <GDLContentStore/NSURL+GCS.h>
|
||||
#include <GDLAccess/EOAdaptorChannel.h>
|
||||
#include <GDLAccess/EOAdaptorContext.h>
|
||||
#include <GDLAccess/EOAttribute.h>
|
||||
#include "common.h"
|
||||
|
||||
@implementation AgenorUserDefaults
|
||||
|
||||
static NSString *uidColumnName = @"uid";
|
||||
|
||||
- (id)initWithTableURL:(NSURL *)_url uid:(NSString *)_uid {
|
||||
if ((self = [super init])) {
|
||||
if (_url == nil || [_uid length] < 1) {
|
||||
[self errorWithFormat:@"tried to create AgenorUserDefaults w/o args!"];
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
self->parent = [[NSUserDefaults standardUserDefaults] retain];
|
||||
self->url = [_url copy];
|
||||
self->uid = [_uid copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (id)init {
|
||||
return [self initWithTableURL:nil uid:nil];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self->attributes release];
|
||||
[self->lastFetch release];
|
||||
[self->parent release];
|
||||
[self->url release];
|
||||
[self->uid release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSURL *)tableURL {
|
||||
return self->url;
|
||||
}
|
||||
- (NSString *)uid {
|
||||
return self->uid;
|
||||
}
|
||||
|
||||
- (NSUserDefaults *)parentDefaults {
|
||||
return self->parent;
|
||||
}
|
||||
|
||||
/* operation */
|
||||
|
||||
- (void)_loadAttributes:(NSArray *)_attrs {
|
||||
NSMutableArray *fields;
|
||||
NSMutableDictionary *attrmap;
|
||||
unsigned i, count;
|
||||
|
||||
fields = [[NSMutableArray alloc] initWithCapacity:16];
|
||||
attrmap = [[NSMutableDictionary alloc] initWithCapacity:16];
|
||||
for (i = 0, count = [_attrs count]; i < count; i++) {
|
||||
EOAttribute *attr;
|
||||
NSString *name;
|
||||
|
||||
attr = [_attrs objectAtIndex:i];
|
||||
name = [attr valueForKey:@"name"];
|
||||
[attrmap setObject:attr forKey:name];
|
||||
|
||||
if (![name isEqual:uidColumnName])
|
||||
[fields addObject:name];
|
||||
}
|
||||
|
||||
ASSIGNCOPY(self->fieldNames, fields);
|
||||
ASSIGNCOPY(self->attributes, attrmap);
|
||||
[attrmap release];
|
||||
[fields release];
|
||||
}
|
||||
|
||||
- (BOOL)primaryFetchProfile {
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *channel;
|
||||
NSDictionary *row;
|
||||
NSException *ex;
|
||||
NSString *sql;
|
||||
NSArray *attrs;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
if ((channel = [cm acquireOpenChannelForURL:[self tableURL]]) == nil) {
|
||||
[self errorWithFormat:@"failed to acquire channel for URL: %@",
|
||||
[self tableURL]];
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* generate SQL */
|
||||
|
||||
sql = [[self tableURL] gcsTableName];
|
||||
sql = [@"SELECT * FROM " stringByAppendingString:sql];
|
||||
sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
|
||||
uidColumnName, [self uid]];
|
||||
|
||||
/* run SQL */
|
||||
|
||||
if ((ex = [channel evaluateExpressionX:sql]) != nil) {
|
||||
[self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
|
||||
[cm releaseChannel:channel];
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* fetch schema */
|
||||
|
||||
attrs = [channel describeResults:NO /* don't beautify */];
|
||||
[self _loadAttributes:attrs];
|
||||
|
||||
/* fetch values */
|
||||
|
||||
row = [channel fetchAttributes:attrs withZone:NULL];
|
||||
self->defFlags.isNew = (row != nil) ? 0 : 1;
|
||||
[channel cancelFetch];
|
||||
|
||||
/* remember values */
|
||||
|
||||
[self->values release]; self->values = nil;
|
||||
self->values = (row != nil)
|
||||
? [row mutableCopy]
|
||||
: [[NSMutableDictionary alloc] initWithCapacity:8];
|
||||
[self->values removeObjectForKey:uidColumnName];
|
||||
|
||||
ASSIGN(self->lastFetch, [NSCalendarDate date]);
|
||||
self->defFlags.modified = 0;
|
||||
|
||||
[cm releaseChannel:channel];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)formatValue:(id)_value forAttribute:(EOAttribute *)_attribute {
|
||||
NSString *s;
|
||||
|
||||
if (![_value isNotNull])
|
||||
return @"NULL";
|
||||
|
||||
if ([[_attribute externalType] hasPrefix:@"int"])
|
||||
return [_value stringValue];
|
||||
|
||||
s = [_value stringValue];
|
||||
s = [s stringByReplacingString:@"'" withString:@"''"];
|
||||
s = [[@"'" stringByAppendingString:s] stringByAppendingString:@"'"];
|
||||
return s;
|
||||
}
|
||||
|
||||
- (NSString *)generateSQLForInsert {
|
||||
NSMutableString *sql;
|
||||
unsigned i, count;
|
||||
|
||||
if ([self->values count] == 0)
|
||||
return nil;
|
||||
|
||||
sql = [NSMutableString stringWithCapacity:2048];
|
||||
|
||||
[sql appendString:@"INSERT INTO "];
|
||||
[sql appendString:[[self tableURL] gcsTableName]];
|
||||
[sql appendString:@" ( uid"];
|
||||
|
||||
for (i = 0, count = [self->fieldNames count]; i < count; i++) {
|
||||
EOAttribute *attr;
|
||||
|
||||
attr = [self->attributes objectForKey:[self->fieldNames objectAtIndex:i]];
|
||||
[sql appendString:@", "];
|
||||
[sql appendString:[attr columnName]];
|
||||
}
|
||||
|
||||
[sql appendString:@") VALUES ("];
|
||||
|
||||
[sql appendString:@"'"];
|
||||
[sql appendString:[self uid]]; // TODO: escaping necessary?
|
||||
[sql appendString:@"'"];
|
||||
|
||||
for (i = 0, count = [self->fieldNames count]; i < count; i++) {
|
||||
EOAttribute *attr;
|
||||
id value;
|
||||
|
||||
attr = [self->attributes objectForKey:[self->fieldNames objectAtIndex:i]];
|
||||
value = [self->values objectForKey:[self->fieldNames objectAtIndex:i]];
|
||||
|
||||
[sql appendString:@", "];
|
||||
[sql appendString:[self formatValue:value forAttribute:attr]];
|
||||
}
|
||||
|
||||
[sql appendString:@")"];
|
||||
return sql;
|
||||
}
|
||||
|
||||
- (NSString *)generateSQLForUpdate {
|
||||
NSMutableString *sql;
|
||||
unsigned i, count;
|
||||
|
||||
if ([self->values count] == 0)
|
||||
return nil;
|
||||
|
||||
sql = [NSMutableString stringWithCapacity:2048];
|
||||
|
||||
[sql appendString:@"UPDATE "];
|
||||
[sql appendString:[[self tableURL] gcsTableName]];
|
||||
[sql appendString:@" SET "];
|
||||
|
||||
for (i = 0, count = [self->fieldNames count]; i < count; i++) {
|
||||
EOAttribute *attr;
|
||||
NSString *name;
|
||||
id value;
|
||||
|
||||
name = [self->fieldNames objectAtIndex:i];
|
||||
value = [self->values objectForKey:name];
|
||||
attr = [self->attributes objectForKey:name];
|
||||
|
||||
if (i != 0) [sql appendString:@", "];
|
||||
[sql appendString:[attr columnName]];
|
||||
[sql appendString:@" = "];
|
||||
[sql appendString:[self formatValue:value forAttribute:attr]];
|
||||
}
|
||||
|
||||
[sql appendString:@" WHERE "];
|
||||
[sql appendString:uidColumnName];
|
||||
[sql appendString:@" = '"];
|
||||
[sql appendString:[self uid]];
|
||||
[sql appendString:@"'"];
|
||||
return sql;
|
||||
}
|
||||
|
||||
- (BOOL)primaryStoreProfile {
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *channel;
|
||||
NSException *ex;
|
||||
NSString *sql;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
if ((channel = [cm acquireOpenChannelForURL:[self tableURL]]) == nil) {
|
||||
[self errorWithFormat:@"failed to acquire channel for URL: %@",
|
||||
[self tableURL]];
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* run SQL */
|
||||
|
||||
sql = self->defFlags.isNew
|
||||
? [self generateSQLForInsert]
|
||||
: [self generateSQLForUpdate];
|
||||
if ((ex = [channel evaluateExpressionX:sql]) != nil) {
|
||||
[self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
|
||||
[cm releaseChannel:channel];
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* commit */
|
||||
|
||||
ex = nil;
|
||||
if ([[channel adaptorContext] hasOpenTransaction])
|
||||
ex = [channel evaluateExpressionX:@"COMMIT TRANSACTION"];
|
||||
|
||||
[cm releaseChannel:channel];
|
||||
|
||||
if (ex != nil) {
|
||||
[self errorWithFormat:@"could not commit transaction for update: %@", ex];
|
||||
return NO;
|
||||
}
|
||||
|
||||
self->defFlags.modified = 0;
|
||||
self->defFlags.isNew = 0;
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)fetchProfile {
|
||||
if (self->values != nil)
|
||||
return YES;
|
||||
|
||||
return [self primaryFetchProfile];
|
||||
}
|
||||
|
||||
- (NSArray *)primaryDefaultNames {
|
||||
if (![self fetchProfile])
|
||||
return nil;
|
||||
|
||||
return self->fieldNames;
|
||||
}
|
||||
|
||||
/* value access */
|
||||
|
||||
- (void)setObject:(id)_value forKey:(NSString *)_key {
|
||||
if (![self fetchProfile])
|
||||
return;
|
||||
|
||||
if (![self->fieldNames containsObject:_key]) {
|
||||
[self errorWithFormat:@"tried to write key: '%@'", _key];
|
||||
return;
|
||||
}
|
||||
|
||||
/* check whether the value is actually modified */
|
||||
if (!self->defFlags.modified) {
|
||||
id old;
|
||||
|
||||
old = [self->values objectForKey:_key];
|
||||
if (old == _value || [old isEqual:_value]) /* value didn't change */
|
||||
return;
|
||||
|
||||
/* we need to this because our typed accessors convert to strings */
|
||||
// TODO: especially problematic with bools
|
||||
if ([_value isKindOfClass:[NSString class]]) {
|
||||
if (![old isKindOfClass:[NSString class]])
|
||||
if ([[old description] isEqualToString:_value])
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* set in hash and mark as modified */
|
||||
[self->values setObject:(_value ? _value : [NSNull null]) forKey:_key];
|
||||
self->defFlags.modified = 1;
|
||||
}
|
||||
|
||||
- (id)objectForKey:(NSString *)_key {
|
||||
id value;
|
||||
|
||||
if (![self fetchProfile])
|
||||
return nil;
|
||||
|
||||
if (![self->fieldNames containsObject:_key])
|
||||
return [self->parent objectForKey:_key];
|
||||
|
||||
value = [self->values objectForKey:_key];
|
||||
return [value isNotNull] ? value : nil;
|
||||
}
|
||||
|
||||
- (void)removeObjectForKey:(NSString *)_key {
|
||||
[self setObject:nil forKey:_key];
|
||||
}
|
||||
|
||||
/* saving changes */
|
||||
|
||||
- (BOOL)synchronize {
|
||||
if (!self->defFlags.modified) /* was not modified */
|
||||
return YES;
|
||||
|
||||
/* ensure fetched data (more or less guaranteed by modified!=0) */
|
||||
if (![self fetchProfile])
|
||||
return NO;
|
||||
|
||||
/* store */
|
||||
if (![self primaryStoreProfile]) {
|
||||
[self primaryFetchProfile];
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* refetch */
|
||||
return [self primaryFetchProfile];
|
||||
}
|
||||
|
||||
- (void)flush {
|
||||
[self->values release]; self->values = nil;
|
||||
[self->fieldNames release]; self->fieldNames = nil;
|
||||
[self->attributes release]; self->attributes = nil;
|
||||
[self->lastFetch release]; self->lastFetch = nil;
|
||||
self->defFlags.modified = 0;
|
||||
self->defFlags.isNew = 0;
|
||||
}
|
||||
|
||||
/* typed accessors */
|
||||
|
||||
- (NSArray *)arrayForKey:(NSString *)_key {
|
||||
id obj = [self objectForKey:_key];
|
||||
return [obj isKindOfClass:[NSArray class]] ? obj : nil;
|
||||
}
|
||||
|
||||
- (NSDictionary *)dictionaryForKey:(NSString *)_key {
|
||||
id obj = [self objectForKey:_key];
|
||||
return [obj isKindOfClass:[NSDictionary class]] ? obj : nil;
|
||||
}
|
||||
|
||||
- (NSData *)dataForKey:(NSString *)_key {
|
||||
id obj = [self objectForKey:_key];
|
||||
return [obj isKindOfClass:[NSData class]] ? obj : nil;
|
||||
}
|
||||
|
||||
- (NSArray *)stringArrayForKey:(NSString *)_key {
|
||||
id obj = [self objectForKey:_key];
|
||||
int n;
|
||||
Class strClass = [NSString class];
|
||||
|
||||
if (![obj isKindOfClass:[NSArray class]])
|
||||
return nil;
|
||||
|
||||
for (n = [obj count]-1; n >= 0; n--) {
|
||||
if (![[obj objectAtIndex:n] isKindOfClass:strClass])
|
||||
return nil;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
- (NSString *)stringForKey:(NSString *)_key {
|
||||
id obj = [self objectForKey:_key];
|
||||
return [obj isKindOfClass:[NSString class]] ? obj : nil;
|
||||
}
|
||||
|
||||
- (BOOL)boolForKey:(NSString *)_key {
|
||||
// TODO: need special support here for int-DB fields
|
||||
id obj;
|
||||
|
||||
if ((obj = [self objectForKey:_key]) == nil)
|
||||
return NO;
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
if ([obj compare:@"YES" options:NSCaseInsensitiveSearch] == NSOrderedSame)
|
||||
return YES;
|
||||
}
|
||||
if ([obj respondsToSelector:@selector(intValue)])
|
||||
return [obj intValue] ? YES : NO;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (float)floatForKey:(NSString *)_key {
|
||||
id obj = [self stringForKey:_key];
|
||||
return (obj != nil) ? [obj floatValue] : 0.0;
|
||||
}
|
||||
- (int)integerForKey:(NSString *)_key {
|
||||
id obj = [self stringForKey:_key];
|
||||
return (obj != nil) ? [obj intValue] : 0;
|
||||
}
|
||||
|
||||
- (void)setBool:(BOOL)value forKey:(NSString *)_key {
|
||||
// TODO: need special support here for int-DB fields
|
||||
[self setObject:(value ? @"YES" : @"NO") forKey:_key];
|
||||
}
|
||||
- (void)setFloat:(float)value forKey:(NSString *)_key {
|
||||
[self setObject:[NSString stringWithFormat:@"%f", value] forKey:_key];
|
||||
}
|
||||
- (void)setInteger:(int)value forKey:(NSString *)_key {
|
||||
[self setObject:[NSString stringWithFormat:@"%d", value] forKey:_key];
|
||||
}
|
||||
|
||||
/* description */
|
||||
|
||||
- (NSString *)description {
|
||||
NSMutableString *ms;
|
||||
|
||||
ms = [NSMutableString stringWithCapacity:16];
|
||||
[ms appendFormat:@"<0x%08X[%@]>", self, NSStringFromClass([self class])];
|
||||
[ms appendFormat:@" uid=%@", self->uid];
|
||||
[ms appendFormat:@" url=%@", [self->url absoluteString]];
|
||||
[ms appendFormat:@" parent=0x%08X", self->parent];
|
||||
[ms appendString:@">"];
|
||||
return ms;
|
||||
}
|
||||
|
||||
@end /* AgenorUserDefaults */
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
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 <Foundation/NSObject.h>
|
||||
|
||||
/*
|
||||
AgenorUserManager
|
||||
|
||||
TODO: document
|
||||
*/
|
||||
|
||||
@class NSString, NSArray, NSURL, NSUserDefaults, NSMutableDictionary, NSTimer;
|
||||
@class NSDictionary;
|
||||
@class iCalPerson;
|
||||
|
||||
@interface AgenorUserManager : NSObject
|
||||
{
|
||||
NSMutableDictionary *cnCache;
|
||||
NSMutableDictionary *serverCache;
|
||||
NSMutableDictionary *uidCache;
|
||||
NSMutableDictionary *emailCache;
|
||||
NSMutableDictionary *shareStoreCache;
|
||||
NSMutableDictionary *shareEMailCache;
|
||||
NSMutableDictionary *changeInternetAccessCache;
|
||||
NSMutableDictionary *internetAutoresponderFlagCache;
|
||||
NSMutableDictionary *intranetAutoresponderFlagCache;
|
||||
NSTimer *gcTimer;
|
||||
}
|
||||
|
||||
+ (id)sharedUserManager;
|
||||
|
||||
- (NSString *)getUIDForEmail:(NSString *)_email;
|
||||
- (NSString *)getEmailForUID:(NSString *)_uid;
|
||||
|
||||
- (NSString *)getUIDForICalPerson:(iCalPerson *)_person;
|
||||
/* may insert NSNulls into returned array if _mapStrictly -> YES */
|
||||
- (NSArray *)getUIDsForICalPersons:(NSArray *)_persons
|
||||
applyStrictMapping:(BOOL)_mapStrictly;
|
||||
|
||||
/* 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;
|
||||
|
||||
- (NSArray *)getSharedMailboxAccountStringsForUID:(NSString *)_uid;
|
||||
- (NSArray *)getSharedMailboxEMailsForUID:(NSString *)_uid;
|
||||
- (NSDictionary *)getSharedMailboxesAndEMailsForUID:(NSString *)_uid;
|
||||
|
||||
- (NSURL *)getFreeBusyURLForUID:(NSString *)_uid;
|
||||
|
||||
- (NSUserDefaults *)getUserDefaultsForUID:(NSString *)_uid;
|
||||
|
||||
- (BOOL)isUserAllowedToChangeSOGoInternetAccess:(NSString *)_uid;
|
||||
|
||||
- (BOOL)isInternetAutoresponderEnabledForUser:(NSString *)_uid;
|
||||
- (BOOL)isIntranetAutoresponderEnabledForUser:(NSString *)_uid;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __AgenorUserManager_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,374 @@
|
||||
2005-08-01 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* added FHS installation (v0.9.70)
|
||||
|
||||
* SOGoObject.m: added class security declarations (previously in
|
||||
product.plist of MainUI) (v0.9.69)
|
||||
|
||||
2005-07-21 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoUser.m: added a method to fetch share/emitter address pairs from
|
||||
the AgenorUserManager (v0.9.68)
|
||||
|
||||
* AgenorUserManager.m: rewrote to use NSMutableDictionary instead of
|
||||
SOGoLRUCache. Flush caches every hour (configurable using
|
||||
'AgenorCacheCheckInterval' default). Added method to retrieve the
|
||||
shares and the emitter emails in one step. (v0.9.67)
|
||||
|
||||
2005-07-20 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* v0.9.66
|
||||
|
||||
* SOGoContentObject.m: properly quote etag
|
||||
|
||||
* SOGoObject.m: changed to check etag when the content is accessed in
|
||||
WebDAV mode and return a 304 if the tag stayed the same.
|
||||
Do not strip quotes from etags in if-*match headers.
|
||||
Properly implement if-none-match for GET requests.
|
||||
|
||||
* SOGoContentObject.m: moved generic etag checking to SOGoObject (to
|
||||
share implementation with Mailer) (v0.9.65)
|
||||
|
||||
2005-07-19 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* AgenorUserManager.m: properly implemented internet/intranet vacation
|
||||
message status detection (v0.9.64)
|
||||
|
||||
2005-07-14 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* v0.9.63
|
||||
|
||||
* SOGoAppointment.[hm]: new API to cancel appointments, NSCopying
|
||||
support
|
||||
|
||||
2005-07-15 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* v0.9.62
|
||||
|
||||
* SOGoGroupFolder.m, SOGoUser.m: fixed a gcc 4.0 warning
|
||||
|
||||
* GNUmakefile.preamble: properly use SYSTEM_LIB_DIR
|
||||
|
||||
* v0.9.61
|
||||
|
||||
* SOGoContentObject.m: fixed a Cocoa warning
|
||||
|
||||
* GNUmakefile.preamble: added proper linking flags for OSX
|
||||
|
||||
2005-07-14 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* v0.9.60
|
||||
|
||||
* SOGoAppointment.[hm]: added 'method' and 'userComment' accessors
|
||||
|
||||
* SOGoAppointmentICalRenderer.m: properly render 'method' of
|
||||
appointment if it's set - otherwise assume 'REQUEST'
|
||||
|
||||
2005-07-14 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoUser.m: added -homeFolderInContext: and
|
||||
-schedulingCalendarInContext: methods (v0.9.59)
|
||||
|
||||
* moved in SOGoUser and SOGoAuthenticator from Main (v0.9.58)
|
||||
|
||||
2005-07-14 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* AgenorUserManager.[hm]: added accessors and cache for the
|
||||
'mineqMelReponse' flag. Please note that the implementation isn't
|
||||
fully fleshed out because the technical specification isn't correct.
|
||||
(v0.9.57)
|
||||
|
||||
* AgenorUserManager.[hm]: added accessors and cache for the
|
||||
'mineqOgoAccesInternet' flag (v0.9.56)
|
||||
|
||||
2005-07-14 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoContentObject.m: added empty davCopy/davMove methods (v0.9.55)
|
||||
|
||||
* v0.9.54
|
||||
|
||||
* SOGoContentObject.m: added support for special 'new' key (server will
|
||||
assign a name and add the new location in a special response header)
|
||||
|
||||
* SOGoFolder.m: added +globallyUniqueObjectId (previously the method
|
||||
was duplicated in each subclass)
|
||||
|
||||
* SOGoContentObject.m: added transactionally save etag-checks in PUT
|
||||
(use the etag value as the baseVersion in the content store)
|
||||
(v0.9.53)
|
||||
|
||||
2005-07-13 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* v0.9.52
|
||||
|
||||
* SOGoObject.m: properly add etag during a GET (if available)
|
||||
|
||||
* SOGoContentObject.m: generate etag from content object version, added
|
||||
methods to check request preconditions, check preconditions prior
|
||||
running a PUT, added new etag after running a PUT
|
||||
|
||||
* SOGoObject.m, SOGoFolder.m: added +version methods to detect fragile
|
||||
base class issues (v0.9.51)
|
||||
|
||||
* SOGoFolder.m: changed to use plain column names (v0.9.50)
|
||||
|
||||
2005-07-12 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* SOGoUserFolder.m: forbid access (403) to SOGoGroupFolders if access
|
||||
is not from the Intranet (v0.9.49)
|
||||
|
||||
2005-07-12 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* AgenorUserDefaults.m: added automagic profile row creation (v0.9.48)
|
||||
|
||||
* AgenorUserDefaults.m: implemented saving of changed profiles
|
||||
(v0.9.47)
|
||||
|
||||
2005-07-12 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* AgenorUserManager.[hm]: new API for extracting UIDs from iCalPersons
|
||||
(v0.9.46)
|
||||
|
||||
2005-07-12 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* v0.9.45
|
||||
|
||||
* AgenorUserDefaults.m: properly fetch profile contents
|
||||
|
||||
* agenor_defaults.m: read operation can now return all defined keys
|
||||
|
||||
* v0.9.44
|
||||
|
||||
* AgenorUserDefaults.m: added typed value accessors and proper
|
||||
initializers
|
||||
|
||||
* AgenorUserManager.m: added 'AgenorProfileURL' default to configure
|
||||
the database location of the user profile table
|
||||
|
||||
* finished agenor_defaults tool
|
||||
|
||||
2005-07-12 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* v0.9.43
|
||||
|
||||
* added agenor_defaults tool to test defaults functionality
|
||||
|
||||
* AgenorUserManager.[hm]: added -getUserDefaultsForUID: method to
|
||||
retrieve the profile of a user (incomplete)
|
||||
|
||||
* added AgenorUserDefaults class (incomplete) as a wrapper for the
|
||||
profile data of Agenor users
|
||||
|
||||
2005-07-08 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* v0.9.42
|
||||
|
||||
* added agenor_emails4uid tool to check whether the
|
||||
uid=>allowed-from-mails discovery in AgenorUserManager works
|
||||
|
||||
* AgenorUserManager.m: added -getSharedMailboxEMailsForUID: method to
|
||||
discover the shared emails the user is allowed to post from,
|
||||
added caching of shared emails and Cyrus-logins
|
||||
|
||||
* WOContext+Agenor.m: use SOGoInternetDetectQualifier for detecting
|
||||
Internet access level (v0.9.41)
|
||||
|
||||
2005-07-08 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* WOContext+Agenor.[hm]: new category for discovering if the current
|
||||
context is via access from the intranet. (v0.9.40)
|
||||
|
||||
2005-07-07 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* added agenor_shares4uid tool to check whether the uid=>shared mailbox
|
||||
discovery in AgenorUserManager works
|
||||
|
||||
* AgenorUserManager.m: fixed a major string scanning bug in
|
||||
_serverCandidatesForMineqMelRoutage: method,
|
||||
added -getSharedMailboxAccountStringsForUID: method to discover
|
||||
shared IMAP4 accounts (v0.9.39)
|
||||
|
||||
2005-07-07 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* AgenorUserManager.m: added a simple -description method (v0.9.38)
|
||||
|
||||
* added agenor_email2uid.m tool to check whether the email=>uid mapping
|
||||
in AgenorUserManager works
|
||||
|
||||
2005-07-06 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* v0.9.37
|
||||
|
||||
* SOGoUserFolder.m: added 'freebusy.ifb' as an object to the
|
||||
collection for proper display via DAV.
|
||||
|
||||
* SOGoAppointmentICalRenderer.m: fixed header inclusion
|
||||
|
||||
* AgenorUserManager.[hm]: added proposed future API for discovering
|
||||
URLs for free/busy information (implementation currently returns
|
||||
nil)
|
||||
|
||||
2005-07-05 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* SOGoAppointment.m: fixed a wrong -release (v0.9.36)
|
||||
|
||||
2005-03-25 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoObject.m: fixed DELETEAction to return a boolean if the delete
|
||||
was successful (required by SoObjectRequestHandler) (v0.9.35)
|
||||
|
||||
2005-03-20 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* changed to use GDLContentStore (v0.9.34)
|
||||
|
||||
2005-03-03 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* SOGoGroupFolder.m: switched logging to NGLogging (v0.9.33)
|
||||
|
||||
2005-03-02 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* NSObject+AptComparison.[hm]: new comparison method. This is used
|
||||
in SOGoAppointmentFolder currently. (v0.9.32)
|
||||
|
||||
2005-02-20 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* AgenorUserManager.m: refactoring of the LDAP fetch code, added the
|
||||
'SOGoFallbackIMAP4Server' default to configure the IMAP4 server when
|
||||
LDAP is disabled (v0.9.31)
|
||||
|
||||
2005-02-17 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* moved in code from libSOGoLogic (unnecessarily a separate library)
|
||||
(v0.9.30)
|
||||
|
||||
2005-02-10 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoObject.m: fixed a warning on MacOSX (v0.9.29)
|
||||
|
||||
2005-02-07 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoObject.h: added prototype for GETAction (v0.9.28)
|
||||
|
||||
2005-02-06 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* added -outlookMessageClass / -outlookFolderClass (v0.9.27)
|
||||
|
||||
2004-10-19 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoFolder: added method -fetchContentStringsAndNamesOfAllObjects
|
||||
which fetches the contents of all folders objects (avoid to use this
|
||||
high overhead method!). Required for iCalendar file generation.
|
||||
(v0.9.26)
|
||||
|
||||
2004-10-08 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoUserFolder.m: enhanced object lookup so that when a Calendar
|
||||
is opened with an extensions (eg "Calendar.ics") (v0.9.25)
|
||||
|
||||
* SOGoFolder.m: added facility to define default extensions (v0.9.24)
|
||||
|
||||
* SOGoObject.m: fixed not implemented return status (501, not 502)
|
||||
(v0.9.23)
|
||||
|
||||
* SOGoUserFolder.m: do not try to fetch file names in this folder
|
||||
(v0.9.22)
|
||||
|
||||
* v0.9.21
|
||||
|
||||
* SOGoContentObject.m: added PUTAction:
|
||||
|
||||
* SOGoObject.m: implemented special WebDAV support in GETAction:
|
||||
|
||||
* SOGoFolder.m: added -toOneRelationshipKeys method (enables listing of
|
||||
contained objects in WebDAV), added container name to logging prefix,
|
||||
explicitly mark as WebDAV collection
|
||||
|
||||
* SOGoContentObject.m: mark as WebDAV non-collection
|
||||
|
||||
2004-10-07 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoUserFolder.m: added toManyRelationshipKeys, marked as WebDAV
|
||||
collection (v0.9.20)
|
||||
|
||||
2004-09-29 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoObject.m: added -fetchSubfolders method to resolve all
|
||||
toManyRelationshipKeys to SOPE objects (v0.9.19)
|
||||
|
||||
2004-09-20 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* SOGoObject.m: added a default GET method which redirects to
|
||||
url + "/view" (v0.9.18)
|
||||
|
||||
* SOGoObject.m(-description): added name of container (v0.9.17)
|
||||
|
||||
2004-09-08 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* SOGoGroupFolder.m: separate -resetFolderCaches method from -sleep
|
||||
(v0.9.16)
|
||||
|
||||
2004-09-08 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* SOGoUserFolder.m: map "Mail" key to SOGoMailAccounts object (v0.9.15)
|
||||
|
||||
2004-09-01 Marcus Mueller <znek@mulle-kybernetik.com>
|
||||
|
||||
* v0.9.14
|
||||
|
||||
* GNUmakefile.preamble: fixed for gsmake 1.9.2 build
|
||||
|
||||
* GNUmakefile: include ../../Version also
|
||||
|
||||
2004-08-26 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* SOGoUserFolder.m: added ability to create Contacts folder (v0.9.13)
|
||||
|
||||
2004-08-24 Maxime Wacker <mwacker@linagora.com>
|
||||
|
||||
* GNUmakefile.preamble: fixes for the build process (v0.9.12)
|
||||
|
||||
2004-08-16 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* SOGoCustomGroupFolder.m: added -initWithUIDs:inContainer: for using
|
||||
the groups folder for internal group fetches (v0.9.11)
|
||||
|
||||
* SOGoContentObject.m: updated multi-save things (which belong into the
|
||||
SOGoAppointmentObject class), implement -sleep to release the content
|
||||
(v0.9.10)
|
||||
|
||||
2004-08-15 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* SOGoContentObject.m: implement first version of -delete (v0.9.9)
|
||||
|
||||
* SOGoObject.[hm], SOGoUserFolder.[hm]: implemented SOPE
|
||||
-ownerInContext: (v0.9.8)
|
||||
|
||||
2004-08-14 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* v0.9.7
|
||||
|
||||
* SOGoGroupFolder.m: renamed -reset method to -sleep (called by SOPE)
|
||||
|
||||
* SOGoObject.m: added SOPE -sleep method (resets container and can be
|
||||
called by subclasses)
|
||||
|
||||
* SOGoGroupFolder.m: made the folder found note log a debug log
|
||||
|
||||
2004-08-11 Helge Hess <helge.hess@skyrix.com>
|
||||
|
||||
* v0.9.6
|
||||
|
||||
* SOGoUserFolder.m: added "Groups" folder name and lookup
|
||||
|
||||
* added: SOGoGroupsFolder, SOGoGroupFolder, SOGoCustomGroupFolder
|
||||
|
||||
2004-07-02 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoObject.m: added -delete method (but not yet implemented)
|
||||
|
||||
2004-06-30 Helge Hess <helge.hess@opengroupware.org>
|
||||
|
||||
* SOGoContentObject.m: added -contentAsString method
|
||||
|
||||
* created ChangeLog
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# GNUstep makefile
|
||||
|
||||
-include ../../config.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
-include ../../Version
|
||||
-include ./Version
|
||||
|
||||
LIBRARY_NAME = libSOGo
|
||||
|
||||
TOOL_NAME = \
|
||||
agenor_email2uid \
|
||||
agenor_shares4uid \
|
||||
agenor_emails4uid \
|
||||
agenor_defaults
|
||||
|
||||
libSOGo_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION)
|
||||
|
||||
libSOGo_HEADER_FILES_DIR = .
|
||||
libSOGo_HEADER_FILES_INSTALL_DIR = /SOGo
|
||||
FHS_HEADER_DIRS = SOGo
|
||||
|
||||
libSOGo_HEADER_FILES = \
|
||||
SOGoObject.h \
|
||||
SOGoFolder.h \
|
||||
SOGoContentObject.h \
|
||||
SOGoUserFolder.h \
|
||||
SOGoGroupsFolder.h \
|
||||
SOGoGroupFolder.h \
|
||||
SOGoCustomGroupFolder.h \
|
||||
\
|
||||
SOGoAppointment.h \
|
||||
AgenorUserManager.h \
|
||||
SOGoLRUCache.h \
|
||||
NSString+iCal.h \
|
||||
NSObject+AptComparison.h \
|
||||
WOContext+Agenor.h \
|
||||
\
|
||||
SOGoAuthenticator.h \
|
||||
SOGoUser.h \
|
||||
|
||||
libSOGo_OBJC_FILES = \
|
||||
SOGoObject.m \
|
||||
SOGoFolder.m \
|
||||
SOGoContentObject.m \
|
||||
SOGoUserFolder.m \
|
||||
SOGoGroupsFolder.m \
|
||||
SOGoGroupFolder.m \
|
||||
SOGoCustomGroupFolder.m \
|
||||
\
|
||||
SOGoAppointment.m \
|
||||
SOGoAppointmentICalRenderer.m \
|
||||
SOGoLRUCache.m \
|
||||
AgenorUserManager.m \
|
||||
NSObject+AptComparison.m \
|
||||
WOContext+Agenor.m \
|
||||
AgenorUserDefaults.m \
|
||||
\
|
||||
SOGoAuthenticator.m \
|
||||
SOGoUser.m \
|
||||
|
||||
# tools
|
||||
|
||||
COMMON_TOOL_FILES = \
|
||||
AgenorUserManager.m \
|
||||
AgenorUserDefaults.m \
|
||||
SOGoLRUCache.m \
|
||||
|
||||
agenor_email2uid_OBJC_FILES += agenor_email2uid.m $(COMMON_TOOL_FILES)
|
||||
agenor_shares4uid_OBJC_FILES += agenor_shares4uid.m $(COMMON_TOOL_FILES)
|
||||
agenor_emails4uid_OBJC_FILES += agenor_emails4uid.m $(COMMON_TOOL_FILES)
|
||||
agenor_defaults_OBJC_FILES += agenor_defaults.m $(COMMON_TOOL_FILES)
|
||||
|
||||
-include GNUmakefile.preamble
|
||||
include $(GNUSTEP_MAKEFILES)/library.make
|
||||
include $(GNUSTEP_MAKEFILES)/tool.make
|
||||
-include GNUmakefile.postamble
|
||||
-include ../../fhslib.make
|
||||
-include ../../fhstools.make
|
||||
@@ -0,0 +1,33 @@
|
||||
# compilation settings
|
||||
|
||||
libSOGo_INCLUDE_DIRS += -I.. -I../../..
|
||||
|
||||
ifneq ($(GNUSTEP_BUILD_DIR),)
|
||||
RELBUILD_DIR_libOGoContentStore = \
|
||||
$(GNUSTEP_BUILD_DIR)/../../OGoContentStore/$(GNUSTEP_OBJ_DIR_NAME)
|
||||
else
|
||||
RELBUILD_DIR_libOGoContentStore = \
|
||||
../../OGoContentStore/$(GNUSTEP_OBJ_DIR)
|
||||
endif
|
||||
|
||||
SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
|
||||
|
||||
libSOGo_LIB_DIRS += \
|
||||
-L$(RELBUILD_DIR_libOGoContentStore)
|
||||
|
||||
libSOGo_LIBRARIES_DEPEND_UPON += \
|
||||
-lOGoContentStore \
|
||||
-lGDLAccess \
|
||||
-lNGObjWeb \
|
||||
-lNGiCal \
|
||||
-lNGMime \
|
||||
-lNGStreams -lNGExtensions -lEOControl \
|
||||
-lXmlRpc -lDOM -lSaxObjC \
|
||||
-lNGLdap
|
||||
|
||||
ADDITIONAL_TOOL_LIBS += \
|
||||
-lGDLContentStore -lGDLAccess \
|
||||
-lNGLdap \
|
||||
-lNGExtensions -lEOControl \
|
||||
-lDOM -lSaxObjC
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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: NSObject+AptComparison.h 620 2005-03-02 19:57:10Z znek $
|
||||
|
||||
#ifndef __SOGo_NSObject_AptComparison_H_
|
||||
#define __SOGo_NSObject_AptComparison_H_
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@interface NSObject (SOGoAptComparison)
|
||||
|
||||
- (NSComparisonResult)compareAptsAscending:(id)_other;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_NSObject_AptComparison_H_ */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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: NSObject+AptComparison.m 620 2005-03-02 19:57:10Z znek $
|
||||
|
||||
#include "NSObject+AptComparison.h"
|
||||
#include <NGExtensions/NGCalendarDateRange.h>
|
||||
#include "common.h"
|
||||
|
||||
@implementation NSObject (SOGoAptComparison)
|
||||
|
||||
- (NSComparisonResult)compareAptsAscending:(id)_other {
|
||||
NSCalendarDate *sd, *ed;
|
||||
NGCalendarDateRange *r1, *r2;
|
||||
NSComparisonResult result;
|
||||
NSTimeInterval t1, t2;
|
||||
|
||||
sd = [self valueForKey:@"startDate"];
|
||||
ed = [self valueForKey:@"endDate"];
|
||||
r1 = [NGCalendarDateRange calendarDateRangeWithStartDate:sd
|
||||
endDate:ed];
|
||||
|
||||
sd = [_other valueForKey:@"startDate"];
|
||||
ed = [_other valueForKey:@"endDate"];
|
||||
r2 = [NGCalendarDateRange calendarDateRangeWithStartDate:sd
|
||||
endDate:ed];
|
||||
|
||||
result = [r1 compare:r2];
|
||||
if (result != NSOrderedSame)
|
||||
return result;
|
||||
|
||||
t1 = [r1 duration];
|
||||
t2 = [r2 duration];
|
||||
if (t1 == t2)
|
||||
return NSOrderedSame;
|
||||
if (t1 > t2)
|
||||
return NSOrderedDescending;
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -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: NSString+iCal.h 577 2005-02-17 14:38:14Z helge $
|
||||
|
||||
|
||||
#ifndef __NSString_iCal_H_
|
||||
#define __NSString_iCal_H_
|
||||
|
||||
// DEPRECATED
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <NGiCal/iCalRenderer.h>
|
||||
|
||||
#endif /* __NSString_iCal_H_ */
|
||||
@@ -0,0 +1,29 @@
|
||||
libSOGo
|
||||
=======
|
||||
|
||||
Common SOGo objects.
|
||||
|
||||
NOTE: the SOPE objects are registered by the Main bundle products.plist.
|
||||
|
||||
Class Hierarchy
|
||||
===============
|
||||
|
||||
[NSObject]
|
||||
SOGoObject
|
||||
SOGoContentObject
|
||||
SOGoFolder
|
||||
SOGoUserFolder - the "home" directory
|
||||
SOGoGroupsFolder - intermediate folder
|
||||
SOGoGroupFolder - a folder representing a set of people
|
||||
SOGoCustomGroupFolder - a custom group (eg '_custom_helge,znek')
|
||||
|
||||
TODO
|
||||
====
|
||||
- why is SOGoUserFolder an OCS folder?
|
||||
|
||||
|
||||
Defaults
|
||||
========
|
||||
|
||||
AgenorCacheCheckInterval - int (default: 1 hour == 3600s)
|
||||
- how often to flush the LDAP caches
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
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 __SOGoAppointment_H_
|
||||
#define __SOGoAppointment_H_
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
|
||||
/*
|
||||
SOGoAppointment
|
||||
|
||||
Wrapper around the iCalendar content of appointments stored in the
|
||||
OGoContentStore.
|
||||
*/
|
||||
|
||||
@class NSString, NSArray, NSCalendarDate, NGCalendarDateRange;
|
||||
@class iCalPerson, iCalEvent, iCalRecurrenceRule;
|
||||
|
||||
@interface SOGoAppointment : NSObject <NSCopying>
|
||||
{
|
||||
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)setUserComment:(NSString *)_userComment;
|
||||
- (NSString *)userComment;
|
||||
|
||||
- (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)setMethod:(NSString *)_method;
|
||||
- (NSString *)method;
|
||||
|
||||
- (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;
|
||||
|
||||
/* actions */
|
||||
|
||||
- (void)increaseSequence;
|
||||
- (void)cancelWithoutIncreasingSequence;
|
||||
- (void)cancelAndIncreaseSequence;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGoAppointment_H_ */
|
||||
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
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 <SaxObjC/SaxObjC.h>
|
||||
#include <NGiCal/NGiCal.h>
|
||||
#include <EOControl/EOControl.h>
|
||||
#include "SOGoAppointmentICalRenderer.h"
|
||||
#include "common.h"
|
||||
|
||||
@interface SOGoAppointment (PrivateAPI)
|
||||
- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons;
|
||||
@end
|
||||
|
||||
@implementation SOGoAppointment
|
||||
|
||||
static id<NSObject,SaxXMLReader> 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];
|
||||
[self->participants release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* NSCopying */
|
||||
|
||||
- (id)copyWithZone:(NSZone *)_zone {
|
||||
SOGoAppointment *new;
|
||||
|
||||
new = [[[self class] allocWithZone:_zone] init];
|
||||
|
||||
new->calendar = [self->calendar copyWithZone:_zone];
|
||||
new->event = [self->event copyWithZone:_zone];
|
||||
new->participants = [self->participants copyWithZone:_zone];
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/* 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)setUserComment:(NSString *)_userComment {
|
||||
[self->event setUserComment:_userComment];
|
||||
}
|
||||
- (NSString *)userComment {
|
||||
return [self->event userComment];
|
||||
}
|
||||
|
||||
- (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];
|
||||
}
|
||||
- (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)setMethod:(NSString *)_method {
|
||||
[self->calendar setMethod:_method];
|
||||
}
|
||||
- (NSString *)method {
|
||||
return [self->calendar method];
|
||||
}
|
||||
|
||||
- (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;
|
||||
|
||||
_email = [_email lowercaseString];
|
||||
partEmails = [[self participants] valueForKey:@"rfc822Email"];
|
||||
partEmails = [partEmails valueForKey:@"lowercaseString"];
|
||||
return [partEmails containsObject:_email];
|
||||
}
|
||||
|
||||
- (iCalPerson *)findParticipantWithEmail:(id)_email {
|
||||
NSArray *ps;
|
||||
unsigned i, count;
|
||||
|
||||
_email = [_email lowercaseString];
|
||||
ps = [self participants];
|
||||
count = [ps count];
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
iCalPerson *p;
|
||||
|
||||
p = [ps objectAtIndex:i];
|
||||
if ([[[p rfc822Email] lowercaseString] 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];
|
||||
}
|
||||
|
||||
/* actions */
|
||||
|
||||
- (void)increaseSequence {
|
||||
[self->event increaseSequence];
|
||||
}
|
||||
|
||||
- (void)cancelWithoutIncreasingSequence {
|
||||
[self setMethod:@"CANCEL"];
|
||||
}
|
||||
- (void)cancelAndIncreaseSequence {
|
||||
[self cancelWithoutIncreasingSequence];
|
||||
[self increaseSequence];
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
@@ -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 <Foundation/NSObject.h>
|
||||
|
||||
/*
|
||||
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_ */
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
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 <NGiCal/NGiCal.h>
|
||||
#include <NGiCal/iCalRenderer.h>
|
||||
#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;
|
||||
NSString *x;
|
||||
|
||||
calendar = [_apt calendar];
|
||||
|
||||
[s appendString:@"BEGIN:VCALENDAR\r\n"];
|
||||
[s appendString:@"METHOD:"];
|
||||
if((x = [calendar method]))
|
||||
[s appendString:[x iCalSafeString]];
|
||||
else
|
||||
[s appendString:@"REQUEST"];
|
||||
[s appendString:@"\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 */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
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 __Main_SOGoAuthenticator_H__
|
||||
#define __Main_SOGoAuthenticator_H__
|
||||
|
||||
#include <NGObjWeb/SoHTTPAuthenticator.h>
|
||||
|
||||
/*
|
||||
SOGoAuthenticator
|
||||
|
||||
This just overrides the login/pwd check method and always returns YES since
|
||||
the password is already checked in Apache.
|
||||
*/
|
||||
|
||||
@interface SOGoAuthenticator : SoHTTPAuthenticator
|
||||
{
|
||||
}
|
||||
|
||||
+ (id)sharedSOGoAuthenticator;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __Main_SOGoAuthenticator_H__ */
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 "SOGoAuthenticator.h"
|
||||
#include "SOGoUser.h"
|
||||
#include "common.h"
|
||||
|
||||
@implementation SOGoAuthenticator
|
||||
|
||||
static SOGoAuthenticator *auth = nil; // THREAD
|
||||
|
||||
+ (id)sharedSOGoAuthenticator {
|
||||
if (auth == nil)
|
||||
auth = [[self alloc] init];
|
||||
return auth;
|
||||
}
|
||||
|
||||
/* check credentials */
|
||||
|
||||
- (BOOL)checkLogin:(NSString *)_login password:(NSString *)_pwd {
|
||||
if ([_login length] == 0)
|
||||
return NO;
|
||||
|
||||
/* we accept any password since it is checked by Apache in front */
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* create SOGoUser */
|
||||
|
||||
- (SoUser *)userInContext:(WOContext *)_ctx {
|
||||
static SoUser *anonymous = nil;
|
||||
NSString *login;
|
||||
NSArray *uroles;
|
||||
|
||||
if (anonymous == nil) {
|
||||
NSArray *ar = [NSArray arrayWithObject:SoRole_Anonymous];
|
||||
anonymous = [[SOGoUser alloc] initWithLogin:@"anonymous" roles:ar];
|
||||
}
|
||||
|
||||
if ((login = [self checkCredentialsInContext:_ctx]) == nil)
|
||||
/* some error (otherwise result would have been anonymous */
|
||||
return nil;
|
||||
|
||||
if ([login isEqualToString:@"anonymous"])
|
||||
return anonymous;
|
||||
|
||||
uroles = [self rolesForLogin:login];
|
||||
return [[[SOGoUser alloc] initWithLogin:login roles:uroles] autorelease];
|
||||
}
|
||||
|
||||
@end /* SOGoAuthenticator */
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
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: SOGoContentObject.h 851 2005-07-20 14:51:39Z helge $
|
||||
|
||||
#ifndef __SOGo_SOGoContentObject_H__
|
||||
#define __SOGo_SOGoContentObject_H__
|
||||
|
||||
#include <SOGo/SOGoObject.h>
|
||||
|
||||
@class NSString, NSException;
|
||||
|
||||
@interface SOGoContentObject : SOGoObject
|
||||
{
|
||||
NSString *ocsPath;
|
||||
NSString *content;
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (void)setOCSPath:(NSString *)_path;
|
||||
- (NSString *)ocsPath;
|
||||
|
||||
/* folder */
|
||||
|
||||
- (NSString *)ocsPathOfContainer;
|
||||
- (GCSFolder *)ocsFolder;
|
||||
|
||||
/* content */
|
||||
|
||||
- (NSString *)contentAsString;
|
||||
- (NSException *)saveContentString:(NSString *)_str
|
||||
baseVersion:(unsigned int)_baseVersion;
|
||||
- (NSException *)saveContentString:(NSString *)_str;
|
||||
- (NSException *)delete;
|
||||
|
||||
/* etag support */
|
||||
|
||||
- (id)davEntityTag;
|
||||
|
||||
/* message type */
|
||||
|
||||
- (NSString *)outlookMessageClass;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_SOGoContentObject_H__ */
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
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 "SOGoContentObject.h"
|
||||
#include "SOGoFolder.h"
|
||||
#include "common.h"
|
||||
#include <GDLContentStore/GCSFolder.h>
|
||||
|
||||
@interface SOGoContentObject(ETag)
|
||||
- (NSArray *)parseETagList:(NSString *)_c;
|
||||
@end
|
||||
|
||||
@implementation SOGoContentObject
|
||||
|
||||
// TODO: check superclass version
|
||||
|
||||
- (void)dealloc {
|
||||
[self->content release];
|
||||
[self->ocsPath release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* notifications */
|
||||
|
||||
- (void)sleep {
|
||||
[self->content release]; self->content = nil;
|
||||
[super sleep];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (BOOL)isFolderish {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setOCSPath:(NSString *)_path {
|
||||
if ([self->ocsPath isEqualToString:_path])
|
||||
return;
|
||||
|
||||
if (self->ocsPath)
|
||||
[self warnWithFormat:@"GCS path is already set! '%@'", _path];
|
||||
|
||||
ASSIGNCOPY(self->ocsPath, _path);
|
||||
}
|
||||
|
||||
- (NSString *)ocsPath {
|
||||
if (self->ocsPath == nil) {
|
||||
NSString *p;
|
||||
|
||||
if ((p = [self ocsPathOfContainer]) != nil) {
|
||||
if (![p hasSuffix:@"/"]) p = [p stringByAppendingString:@"/"];
|
||||
p = [p stringByAppendingString:[self nameInContainer]];
|
||||
self->ocsPath = [p copy];
|
||||
}
|
||||
}
|
||||
return self->ocsPath;
|
||||
}
|
||||
|
||||
- (NSString *)ocsPathOfContainer {
|
||||
if (![[self container] respondsToSelector:@selector(ocsPath)])
|
||||
return nil;
|
||||
|
||||
return [[self container] ocsPath];
|
||||
}
|
||||
|
||||
- (GCSFolder *)ocsFolder {
|
||||
if (![[self container] respondsToSelector:@selector(ocsFolder)])
|
||||
return nil;
|
||||
|
||||
return [[self container] ocsFolder];
|
||||
}
|
||||
|
||||
/* content */
|
||||
|
||||
- (NSString *)contentAsString {
|
||||
GCSFolder *folder;
|
||||
|
||||
if (self->content != nil)
|
||||
return self->content;
|
||||
|
||||
if ((folder = [self ocsFolder]) == nil) {
|
||||
[self errorWithFormat:@"Did not find folder of content object."];
|
||||
return nil;
|
||||
}
|
||||
|
||||
self->content = [[folder fetchContentWithName:[self nameInContainer]] copy];
|
||||
return self->content;
|
||||
}
|
||||
|
||||
- (NSException *)saveContentString:(NSString *)_str
|
||||
baseVersion:(unsigned int)_baseVersion
|
||||
{
|
||||
/* Note: "iCal multifolder saves" are implemented in the apt subclass! */
|
||||
GCSFolder *folder;
|
||||
NSException *ex;
|
||||
|
||||
if ((folder = [self ocsFolder]) == nil) {
|
||||
[self errorWithFormat:@"Did not find folder of content object."];
|
||||
return nil;
|
||||
}
|
||||
|
||||
ex = [folder writeContent:_str toName:[self nameInContainer]
|
||||
baseVersion:_baseVersion];
|
||||
if (ex != nil) {
|
||||
[self errorWithFormat:@"write failed: %@", ex];
|
||||
return ex;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
- (NSException *)saveContentString:(NSString *)_str {
|
||||
return [self saveContentString:_str baseVersion:0 /* don't check */];
|
||||
}
|
||||
|
||||
- (NSException *)delete {
|
||||
/* Note: "iCal multifolder saves" are implemented in the apt subclass! */
|
||||
GCSFolder *folder;
|
||||
NSException *ex;
|
||||
|
||||
// TODO: add precondition check? (or add DELETEAction?)
|
||||
|
||||
if ((folder = [self ocsFolder]) == nil) {
|
||||
[self errorWithFormat:@"Did not find folder of content object."];
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ((ex = [folder deleteContentWithName:[self nameInContainer]])) {
|
||||
[self errorWithFormat:@"delete failed: %@", ex];
|
||||
return ex;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* actions */
|
||||
|
||||
- (id)PUTAction:(WOContext *)_ctx {
|
||||
WORequest *rq;
|
||||
NSException *error;
|
||||
unsigned int baseVersion;
|
||||
id etag, tmp;
|
||||
BOOL needsLocation;
|
||||
|
||||
if ((error = [self matchesRequestConditionInContext:_ctx]) != nil)
|
||||
return error;
|
||||
|
||||
rq = [_ctx request];
|
||||
|
||||
/* check whether its a request to the 'special' 'new' location */
|
||||
/*
|
||||
Note: this is kinda hack. The OGo ZideStore detects writes to 'new' as
|
||||
object creations and will assign a server side identifier. Most
|
||||
current GroupDAV clients rely on this behaviour, so we reproduce it
|
||||
here.
|
||||
A correct client would loop until it has a name which doesn't not
|
||||
yet exist (by using if-none-match).
|
||||
*/
|
||||
needsLocation = NO;
|
||||
tmp = [[self nameInContainer] stringByDeletingPathExtension];
|
||||
if ([tmp isEqualToString:@"new"]) {
|
||||
tmp = [[[self container] class] globallyUniqueObjectId];
|
||||
needsLocation = YES;
|
||||
|
||||
[self debugWithFormat:
|
||||
@"reassigned a new location for special new-location: %@", tmp];
|
||||
|
||||
/* kinda dangerous */
|
||||
ASSIGNCOPY(self->nameInContainer, tmp);
|
||||
ASSIGN(self->ocsPath, nil);
|
||||
}
|
||||
|
||||
/* determine base version from etag in if-match header */
|
||||
/*
|
||||
Note: The -matchesRequestConditionInContext: already checks whether the
|
||||
etag matches and returns an HTTP exception in case it doesn't.
|
||||
We retrieve the etag again here to _ensure_ a transactionally save
|
||||
commit.
|
||||
(between the check and the update a change could have been done)
|
||||
*/
|
||||
tmp = [rq headerForKey:@"if-match"];
|
||||
tmp = [self parseETagList:tmp];
|
||||
etag = nil;
|
||||
if ([tmp count] > 0) {
|
||||
if ([tmp count] > 1) {
|
||||
/*
|
||||
Note: we would have to attempt a save for _each_ of the etags being
|
||||
passed in! In practice most WebDAV clients submit exactly one
|
||||
etag.
|
||||
*/
|
||||
[self warnWithFormat:
|
||||
@"Got multiple if-match etags from client, only attempting to "
|
||||
@"save with the first: %@", tmp];
|
||||
}
|
||||
|
||||
etag = [tmp objectAtIndex:0];
|
||||
}
|
||||
baseVersion = ([etag length] > 0)
|
||||
? [etag unsignedIntValue]
|
||||
: 0 /* 0 means 'do not check' */;
|
||||
|
||||
/* attempt a save */
|
||||
|
||||
if ((error = [self saveContentString:[rq contentAsString]
|
||||
baseVersion:baseVersion]) != nil)
|
||||
return error;
|
||||
|
||||
/* setup response */
|
||||
|
||||
// TODO: this should be automatic in the SoDispatcher if we return nil?
|
||||
[[_ctx response] setStatus:201 /* Created */];
|
||||
|
||||
if ((etag = [self davEntityTag]) != nil)
|
||||
[[_ctx response] setHeader:etag forKey:@"etag"];
|
||||
|
||||
if (needsLocation) {
|
||||
[[_ctx response] setHeader:[self baseURLInContext:_ctx]
|
||||
forKey:@"location"];
|
||||
}
|
||||
|
||||
return [_ctx response];
|
||||
}
|
||||
|
||||
/* E-Tags */
|
||||
|
||||
- (id)davEntityTag {
|
||||
// TODO: cache tag in ivar? => if you do, remember to flush after PUT
|
||||
GCSFolder *folder;
|
||||
char buf[64];
|
||||
|
||||
if ((folder = [self ocsFolder]) == nil) {
|
||||
[self errorWithFormat:@"Did not find folder of content object."];
|
||||
return nil;
|
||||
}
|
||||
|
||||
sprintf(buf, "\"gcs%08d\"",
|
||||
[[folder versionOfContentWithName:[self nameInContainer]]
|
||||
unsignedIntValue]);
|
||||
return [NSString stringWithCString:buf];
|
||||
}
|
||||
|
||||
/* WebDAV */
|
||||
|
||||
- (NSException *)davMoveToTargetObject:(id)_target newName:(NSString *)_name
|
||||
inContext:(id)_ctx
|
||||
{
|
||||
/*
|
||||
Note: even for new objects we won't get a new name but a preinstantiated
|
||||
object representing the new one.
|
||||
*/
|
||||
[self logWithFormat:
|
||||
@"TODO: move not implemented:\n target: %@\n new name: %@",
|
||||
_target, _name];
|
||||
return [NSException exceptionWithHTTPStatus:405 /* not allowed */
|
||||
reason:@"this object cannot be copied via WebDAV"];
|
||||
}
|
||||
|
||||
- (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name
|
||||
inContext:(id)_ctx
|
||||
{
|
||||
/*
|
||||
Note: even for new objects we won't get a new name but a preinstantiated
|
||||
object representing the new one.
|
||||
*/
|
||||
[self logWithFormat:
|
||||
@"TODO: copy not implemented:\n target: %@\n new name: %@",
|
||||
_target, _name];
|
||||
return [NSException exceptionWithHTTPStatus:405 /* not allowed */
|
||||
reason:@"this object cannot be copied via WebDAV"];
|
||||
}
|
||||
|
||||
- (BOOL)davIsCollection {
|
||||
return [self isFolderish];
|
||||
}
|
||||
|
||||
/* message type */
|
||||
|
||||
- (NSString *)outlookMessageClass {
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* description */
|
||||
|
||||
- (void)appendAttributesToDescription:(NSMutableString *)_ms {
|
||||
[super appendAttributesToDescription:_ms];
|
||||
|
||||
[_ms appendFormat:@" ocs=%@", [self ocsPath]];
|
||||
}
|
||||
|
||||
@end /* SOGoContentObject */
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
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: SOGoCustomGroupFolder.h 107 2004-06-30 10:26:46Z helge $
|
||||
|
||||
#ifndef __SOGo_SOGoCustomGroupFolder_H__
|
||||
#define __SOGo_SOGoCustomGroupFolder_H__
|
||||
|
||||
#include <SOGo/SOGoGroupFolder.h>
|
||||
|
||||
/*
|
||||
SOGoCustomGroupFolder
|
||||
same parent/child like SOGoGroupFolder
|
||||
|
||||
Note: parent folder can be different if instantiated for internal use.
|
||||
|
||||
Note: you can use this folder for internal handling of groups! Eg aggregate
|
||||
Calendar fetches.
|
||||
|
||||
This is a specific group folder for 'custom' groups. Group members are
|
||||
currently encoded as the folder name in the URL like
|
||||
_custom_znek,helge
|
||||
*/
|
||||
|
||||
@class NSArray;
|
||||
|
||||
@interface SOGoCustomGroupFolder : SOGoGroupFolder
|
||||
{
|
||||
NSArray *uids;
|
||||
}
|
||||
|
||||
- (id)initWithUIDs:(NSArray *)_uids inContainer:(id)_container;
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSArray *)uids;
|
||||
|
||||
/* pathes */
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_SOGoCustomGroupFolder_H__ */
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
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: SOGoCustomGroupFolder.m 115 2004-06-30 11:57:37Z helge $
|
||||
|
||||
#include "SOGoCustomGroupFolder.h"
|
||||
#include "common.h"
|
||||
|
||||
@implementation SOGoCustomGroupFolder
|
||||
|
||||
static NSString *SOGoUIDSeparator = @",";
|
||||
|
||||
- (id)initWithUIDs:(NSArray *)_uids inContainer:(id)_container {
|
||||
if ((self = [self initWithName:nil inContainer:_container])) {
|
||||
self->uids = [_uids copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self->uids release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSArray *)unescapeURLComponents:(NSArray *)_parts {
|
||||
#warning TODO: implement URL UID unescaping if necessary
|
||||
// TODO: who calls this for what?
|
||||
// Note: remember URL encoding!
|
||||
return _parts;
|
||||
}
|
||||
|
||||
- (NSArray *)uids {
|
||||
NSArray *a;
|
||||
NSString *s;
|
||||
|
||||
if (self->uids != nil)
|
||||
return self->uids;
|
||||
|
||||
s = [self nameInContainer];
|
||||
if (![s hasPrefix:@"_custom_"]) {
|
||||
[self logWithFormat:@"WARNING: incorrect custom group folder name: '%@'",
|
||||
s];
|
||||
return nil;
|
||||
}
|
||||
|
||||
s = [s substringFromIndex:8];
|
||||
a = [s componentsSeparatedByString:SOGoUIDSeparator];
|
||||
a = [self unescapeURLComponents:a];
|
||||
self->uids = [a copy];
|
||||
|
||||
if ([self->uids count] < 2)
|
||||
[self debugWithFormat:@"Note: less than two custom group members!"];
|
||||
|
||||
return self->uids;
|
||||
}
|
||||
|
||||
/* display name */
|
||||
|
||||
- (NSString *)davDisplayName {
|
||||
NSArray *a;
|
||||
unsigned count;
|
||||
|
||||
a = [self uids];
|
||||
if ((count = [a count]) == 0)
|
||||
return @"empty";
|
||||
if (count == 1)
|
||||
return [a objectAtIndex:0];
|
||||
|
||||
if (count < 6) {
|
||||
NSMutableString *ms;
|
||||
unsigned i;
|
||||
|
||||
ms = [NSMutableString stringWithCapacity:64];
|
||||
for (i = 0; i < count; i++) {
|
||||
if (i != 0) [ms appendString:@"|"];
|
||||
[ms appendString:[a objectAtIndex:i]];
|
||||
if ([ms length] > 60) {
|
||||
ms = nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ms != nil) return ms;
|
||||
}
|
||||
|
||||
// TODO: localize 'members' (UI component task?)
|
||||
return [NSString stringWithFormat:@"Members: %d", count];
|
||||
}
|
||||
|
||||
@end /* SOGoCustomGroupFolder */
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
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 __SOGo_SOGoFolder_H__
|
||||
#define __SOGo_SOGoFolder_H__
|
||||
|
||||
#include <SOGo/SOGoObject.h>
|
||||
|
||||
@class NSString, NSArray, NSDictionary;
|
||||
@class GCSFolder;
|
||||
|
||||
/*
|
||||
SOGoFolder
|
||||
|
||||
A common superclass for folders stored in GCS. Already deals with all GCS
|
||||
folder specific things.
|
||||
|
||||
Important: folders should NOT retain the context! Otherwise you might get
|
||||
cyclic references.
|
||||
*/
|
||||
|
||||
@interface SOGoFolder : SOGoObject
|
||||
{
|
||||
NSString *ocsPath;
|
||||
GCSFolder *ocsFolder;
|
||||
}
|
||||
|
||||
+ (NSString *)globallyUniqueObjectId;
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (void)setOCSPath:(NSString *)_Path;
|
||||
- (NSString *)ocsPath;
|
||||
|
||||
- (GCSFolder *)ocsFolderForPath:(NSString *)_path;
|
||||
- (GCSFolder *)ocsFolder;
|
||||
|
||||
/* lower level fetches */
|
||||
|
||||
- (NSArray *)fetchContentObjectNames;
|
||||
- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects;
|
||||
|
||||
/* folder type */
|
||||
|
||||
- (NSString *)outlookFolderClass;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_SOGoFolder_H__ */
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
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 "SOGoFolder.h"
|
||||
#include "common.h"
|
||||
#include <GDLContentStore/GCSFolderManager.h>
|
||||
#include <GDLContentStore/GCSFolder.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@implementation SOGoFolder
|
||||
|
||||
+ (int)version {
|
||||
return [super version] + 0 /* v0 */;
|
||||
}
|
||||
+ (void)initialize {
|
||||
NSAssert2([super version] == 0,
|
||||
@"invalid superclass (%@) version %i !",
|
||||
NSStringFromClass([self superclass]), [super version]);
|
||||
}
|
||||
|
||||
+ (NSString *)globallyUniqueObjectId {
|
||||
/*
|
||||
4C08AE1A-A808-11D8-AC5A-000393BBAFF6
|
||||
SOGo-Web-28273-18283-288182
|
||||
printf( "%x", *(int *) &f);
|
||||
*/
|
||||
static int pid = 0;
|
||||
static int sequence = 0;
|
||||
static float rndm = 0;
|
||||
float f;
|
||||
|
||||
if (pid == 0) { /* break if we fork ;-) */
|
||||
pid = getpid();
|
||||
rndm = random();
|
||||
}
|
||||
sequence++;
|
||||
f = [[NSDate date] timeIntervalSince1970];
|
||||
return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
|
||||
pid, *(int *)&f, sequence++, random];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self->ocsFolder release];
|
||||
[self->ocsPath release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (BOOL)isFolderish {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setOCSPath:(NSString *)_path {
|
||||
if ([self->ocsPath isEqualToString:_path])
|
||||
return;
|
||||
|
||||
if (self->ocsPath)
|
||||
[self warnWithFormat:@"GCS path is already set! '%@'", _path];
|
||||
|
||||
ASSIGNCOPY(self->ocsPath, _path);
|
||||
}
|
||||
- (NSString *)ocsPath {
|
||||
return self->ocsPath;
|
||||
}
|
||||
|
||||
- (GCSFolderManager *)folderManager {
|
||||
return [GCSFolderManager defaultFolderManager];
|
||||
}
|
||||
- (GCSFolder *)ocsFolderForPath:(NSString *)_path {
|
||||
return [[self folderManager] folderAtPath:_path];
|
||||
}
|
||||
- (GCSFolder *)ocsFolder {
|
||||
if (self->ocsFolder != nil)
|
||||
return [self->ocsFolder isNotNull] ? self->ocsFolder : nil;
|
||||
|
||||
self->ocsFolder = [[self ocsFolderForPath:[self ocsPath]] retain];
|
||||
return self->ocsFolder;
|
||||
}
|
||||
|
||||
- (NSArray *)fetchContentObjectNames {
|
||||
NSArray *fields, *records;
|
||||
|
||||
fields = [NSArray arrayWithObject:@"c_name"];
|
||||
records = [[self ocsFolder] fetchFields:fields matchingQualifier:nil];
|
||||
if (![records isNotNull]) {
|
||||
[self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
if ([records isKindOfClass:[NSException class]])
|
||||
return records;
|
||||
return [records valueForKey:@"c_name"];
|
||||
}
|
||||
- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects {
|
||||
NSDictionary *files;
|
||||
|
||||
files = [[self ocsFolder] fetchContentsOfAllFiles];
|
||||
if (![files isNotNull]) {
|
||||
[self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
|
||||
return nil;
|
||||
}
|
||||
if ([files isKindOfClass:[NSException class]])
|
||||
return files;
|
||||
return files;
|
||||
}
|
||||
|
||||
/* reflection */
|
||||
|
||||
- (NSString *)defaultFilenameExtension {
|
||||
/*
|
||||
Override to add an extension to a filename
|
||||
|
||||
Note: be careful with that, needs to be consistent with object lookup!
|
||||
*/
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *)toOneRelationshipKeys {
|
||||
/* toOneRelationshipKeys are the 'files' contained in a folder */
|
||||
NSMutableArray *ma;
|
||||
NSArray *names;
|
||||
NSString *ext;
|
||||
unsigned i, count;
|
||||
|
||||
if ((names = [self fetchContentObjectNames]) == nil)
|
||||
return names;
|
||||
|
||||
if ((count = [names count]) == 0)
|
||||
return names;
|
||||
|
||||
if ((ext = [self defaultFilenameExtension]) == nil)
|
||||
return names;
|
||||
|
||||
ma = [NSMutableArray arrayWithCapacity:count];
|
||||
for (i = 0; i < count; i++) {
|
||||
NSRange r;
|
||||
NSString *name;
|
||||
|
||||
name = [names objectAtIndex:i];
|
||||
r = [name rangeOfString:@"."];
|
||||
if (r.length == 0)
|
||||
name = [[name stringByAppendingString:@"."] stringByAppendingString:ext];
|
||||
|
||||
[ma addObject:name];
|
||||
}
|
||||
return ma;
|
||||
}
|
||||
|
||||
/* WebDAV */
|
||||
|
||||
- (BOOL)davIsCollection {
|
||||
return [self isFolderish];
|
||||
}
|
||||
|
||||
/* folder type */
|
||||
|
||||
- (NSString *)outlookFolderClass {
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* description */
|
||||
|
||||
- (void)appendAttributesToDescription:(NSMutableString *)_ms {
|
||||
[super appendAttributesToDescription:_ms];
|
||||
|
||||
[_ms appendFormat:@" ocs=%@", [self ocsPath]];
|
||||
}
|
||||
|
||||
- (NSString *)loggingPrefix {
|
||||
return [NSString stringWithFormat:@"<0x%08X[%@]:%@>",
|
||||
self, NSStringFromClass([self class]),
|
||||
[self nameInContainer]];
|
||||
}
|
||||
|
||||
@end /* SOGoFolder */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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: SOGoGroupFolder.h 107 2004-06-30 10:26:46Z helge $
|
||||
|
||||
#ifndef __SOGo_SOGoGroupFolder_H__
|
||||
#define __SOGo_SOGoGroupFolder_H__
|
||||
|
||||
#include <SOGo/SOGoObject.h>
|
||||
|
||||
/*
|
||||
SOGoGroupFolder
|
||||
Parent object: the SOGoGroupsFolder
|
||||
Child objects:
|
||||
*/
|
||||
|
||||
@class NSArray, NSDictionary;
|
||||
|
||||
@interface SOGoGroupFolder : SOGoObject
|
||||
{
|
||||
NSDictionary *uidToFolder;
|
||||
NSArray *folders;
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSArray *)uids;
|
||||
|
||||
/* folder management */
|
||||
|
||||
- (NSArray *)memberFolders;
|
||||
- (id)folderForUID:(NSString *)_uid;
|
||||
|
||||
- (void)resetFolderCaches;
|
||||
- (void)sleep;
|
||||
|
||||
/* pathes */
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_SOGoGroupFolder_H__ */
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
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: SOGoGroupFolder.m 115 2004-06-30 11:57:37Z helge $
|
||||
|
||||
#include "SOGoGroupFolder.h"
|
||||
#include "common.h"
|
||||
|
||||
@implementation SOGoGroupFolder
|
||||
|
||||
static NGLogger *logger = nil;
|
||||
|
||||
+ (void)initialize {
|
||||
NGLoggerManager *lm;
|
||||
static BOOL didInit = NO;
|
||||
|
||||
if (didInit) return;
|
||||
didInit = YES;
|
||||
|
||||
lm = [NGLoggerManager defaultLoggerManager];
|
||||
logger = [lm loggerForDefaultKey:@"SOGoGroupFolderDebugEnabled"];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self->uidToFolder release];
|
||||
[self->folders release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* logging */
|
||||
|
||||
- (id)debugLogger {
|
||||
return logger;
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSArray *)uids {
|
||||
[self errorWithFormat:@"instantiated abstract Group folder class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* folder management */
|
||||
|
||||
- (id)_primaryLookupFolderForUID:(NSString *)_uid inContext:(id)_ctx {
|
||||
NSException *error = nil;
|
||||
NSArray *path;
|
||||
id ctx, result;
|
||||
|
||||
/* create subcontext, so that we don't destroy our environment */
|
||||
|
||||
if ((ctx = [_ctx createSubContext]) == nil) {
|
||||
[self errorWithFormat:@"could not create SOPE subcontext!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* build path */
|
||||
|
||||
path = _uid != nil ? [NSArray arrayWithObjects:&_uid count:1] : nil;
|
||||
|
||||
/* traverse path */
|
||||
|
||||
result = [[ctx application] traversePathArray:path inContext:ctx
|
||||
error:&error acquire:NO];
|
||||
if (error != nil) {
|
||||
[self errorWithFormat:@"folder lookup failed (uid=%@): %@",
|
||||
_uid, error];
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (logger)
|
||||
[self debugWithFormat:@"Note: got folder for uid %@ path %@: %@",
|
||||
_uid, [path componentsJoinedByString:@"=>"], result];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)_setupFolders {
|
||||
WOContext *ctx;
|
||||
NSMutableDictionary *md;
|
||||
NSMutableArray *ma;
|
||||
NSArray *luids;
|
||||
unsigned i, count;
|
||||
|
||||
if (self->uidToFolder != nil)
|
||||
return;
|
||||
if ((luids = [self uids]) == nil)
|
||||
return;
|
||||
|
||||
ctx = [[WOApplication application] context];
|
||||
|
||||
count = [luids count];
|
||||
ma = [NSMutableArray arrayWithCapacity:count + 1];
|
||||
md = [NSMutableDictionary dictionaryWithCapacity:count];
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
NSString *uid;
|
||||
id folder;
|
||||
|
||||
uid = [luids objectAtIndex:i];
|
||||
folder = [self _primaryLookupFolderForUID:uid inContext:ctx];
|
||||
|
||||
if ([folder isNotNull]) {
|
||||
[md setObject:folder forKey:uid];
|
||||
[ma addObject:folder];
|
||||
}
|
||||
else
|
||||
[ma addObject:[NSNull null]];
|
||||
}
|
||||
|
||||
/* fix results */
|
||||
self->uidToFolder = [md copy];
|
||||
self->folders = [[NSArray alloc] initWithArray:ma];
|
||||
}
|
||||
|
||||
- (NSArray *)memberFolders {
|
||||
[self _setupFolders];
|
||||
return self->folders;
|
||||
}
|
||||
|
||||
- (id)folderForUID:(NSString *)_uid {
|
||||
[self _setupFolders];
|
||||
|
||||
if ([_uid length] == 0)
|
||||
return nil;
|
||||
|
||||
return [self->uidToFolder objectForKey:_uid];
|
||||
}
|
||||
|
||||
- (void)resetFolderCaches {
|
||||
[self->uidToFolder release]; self->uidToFolder = nil;
|
||||
[self->folders release]; self->folders = nil;
|
||||
}
|
||||
- (void)sleep {
|
||||
[self resetFolderCaches];
|
||||
[super sleep];
|
||||
}
|
||||
|
||||
/* SOPE */
|
||||
|
||||
- (BOOL)isFolderish {
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* looking up shared objects */
|
||||
|
||||
- (SOGoGroupsFolder *)lookupGroupsFolder {
|
||||
return [[self container] lookupGroupsFolder];
|
||||
}
|
||||
|
||||
/* pathes */
|
||||
|
||||
/* name lookup */
|
||||
|
||||
- (id)groupCalendar:(NSString *)_key inContext:(id)_ctx {
|
||||
static Class calClass = Nil;
|
||||
id calendar;
|
||||
|
||||
if (calClass == Nil)
|
||||
calClass = NSClassFromString(@"SOGoGroupAppointmentFolder");
|
||||
if (calClass == Nil) {
|
||||
[self errorWithFormat:@"missing SOGoGroupAppointmentFolder class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
calendar = [[calClass alloc] initWithName:_key inContainer:self];
|
||||
|
||||
// TODO: should we pass over the uids in questions or should the
|
||||
// appointment folder query its container for that info?
|
||||
|
||||
return [calendar autorelease];
|
||||
}
|
||||
|
||||
- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
|
||||
id obj;
|
||||
|
||||
/* first check attributes directly bound to the application */
|
||||
if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
|
||||
return obj;
|
||||
|
||||
if ([_key isEqualToString:@"Calendar"])
|
||||
return [self groupCalendar:_key inContext:_ctx];
|
||||
|
||||
/* return 404 to stop acquisition */
|
||||
return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
|
||||
}
|
||||
|
||||
@end /* SOGoGroupFolder */
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
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: SOGoGroupsFolder.h 107 2004-06-30 10:26:46Z helge $
|
||||
|
||||
#ifndef __SOGo_SOGoGroupsFolder_H__
|
||||
#define __SOGo_SOGoGroupsFolder_H__
|
||||
|
||||
#include <SOGo/SOGoObject.h>
|
||||
|
||||
/*
|
||||
SOGoGroupsFolder
|
||||
Parent object: the SOGoUserFolder
|
||||
Child objects: SOGoGroupFolder objects
|
||||
'_custom_*': SOGoCustomGroupFolder
|
||||
|
||||
This object represents a collection of groups, its the "Groups" in such a
|
||||
path:
|
||||
/SOGo/so/znek/Groups/sales
|
||||
|
||||
It also acts as a factory for the proper group folders, eg "custom" groups
|
||||
(arbitary person collections) or later on cookie based configured groups or
|
||||
groups stored in LDAP.
|
||||
*/
|
||||
|
||||
@class NSString;
|
||||
|
||||
@interface SOGoGroupsFolder : SOGoObject
|
||||
{
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
/* looking up shared objects */
|
||||
|
||||
- (SOGoGroupsFolder *)lookupGroupsFolder;
|
||||
|
||||
/* pathes */
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_SOGoGroupsFolder_H__ */
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
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: SOGoGroupsFolder.m 115 2004-06-30 11:57:37Z helge $
|
||||
|
||||
#include "SOGoGroupsFolder.h"
|
||||
#include "common.h"
|
||||
|
||||
@implementation SOGoGroupsFolder
|
||||
|
||||
- (void)dealloc {
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
/* SOPE */
|
||||
|
||||
- (BOOL)isFolderish {
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* looking up shared objects */
|
||||
|
||||
- (SOGoGroupsFolder *)lookupGroupsFolder {
|
||||
return self;
|
||||
}
|
||||
|
||||
/* pathes */
|
||||
|
||||
/* name lookup */
|
||||
|
||||
- (id)customGroup:(NSString *)_key inContext:(id)_ctx {
|
||||
static Class groupClass = Nil;
|
||||
id group;
|
||||
|
||||
if (groupClass == Nil)
|
||||
groupClass = NSClassFromString(@"SOGoCustomGroupFolder");
|
||||
if (groupClass == Nil) {
|
||||
[self logWithFormat:@"ERROR: missing SOGoCustomGroupFolder class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
group = [[groupClass alloc] initWithName:_key inContainer:self];
|
||||
return [group autorelease];
|
||||
}
|
||||
|
||||
- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
|
||||
id obj;
|
||||
|
||||
/* first check attributes directly bound to the application */
|
||||
if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
|
||||
return obj;
|
||||
|
||||
if ([_key hasPrefix:@"_custom_"])
|
||||
return [self customGroup:_key inContext:_ctx];
|
||||
|
||||
/* return 404 to stop acquisition */
|
||||
return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
|
||||
}
|
||||
|
||||
@end /* SOGoGroupsFolder */
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __SOGoLRUCache_H_
|
||||
#define __SOGoLRUCache_H_
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@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_ */
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "SOGoLRUCache.h"
|
||||
#include "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
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
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 __SoObjects_SOGoObject_H__
|
||||
#define __SoObjects_SOGoObject_H__
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
/*
|
||||
SOGoObject
|
||||
|
||||
This is the abstract class used by all SOGo SoObjects. It contains the
|
||||
ability to track a container as well as the key the object was invoked with.
|
||||
|
||||
In addition it provides some generic methods like user or group folder
|
||||
lookup.
|
||||
*/
|
||||
|
||||
@class NSString, NSArray, NSMutableString, NSException;
|
||||
@class GCSFolderManager, GCSFolder;
|
||||
@class SOGoUserFolder, SOGoGroupsFolder;
|
||||
|
||||
@interface SOGoObject : NSObject
|
||||
{
|
||||
NSString *nameInContainer;
|
||||
id container;
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)_name inContainer:(id)_container;
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSString *)nameInContainer;
|
||||
- (id)container;
|
||||
|
||||
/* ownership */
|
||||
|
||||
- (NSString *)ownerInContext:(id)_ctx;
|
||||
|
||||
/* looking up shared objects */
|
||||
|
||||
- (SOGoUserFolder *)lookupUserFolder;
|
||||
- (SOGoGroupsFolder *)lookupGroupsFolder;
|
||||
|
||||
- (void)sleep;
|
||||
|
||||
/* hierarchy */
|
||||
|
||||
- (NSArray *)fetchSubfolders; /* uses toManyRelationshipKeys */
|
||||
|
||||
/* operations */
|
||||
|
||||
- (NSException *)delete;
|
||||
- (id)GETAction:(id)_ctx;
|
||||
|
||||
/* etag support */
|
||||
|
||||
- (NSException *)matchesRequestConditionInContext:(id)_ctx;
|
||||
|
||||
/* description */
|
||||
|
||||
- (void)appendAttributesToDescription:(NSMutableString *)_ms;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SoObjects_SOGoObject_H__ */
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
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 "SOGoObject.h"
|
||||
#include "SOGoUserFolder.h"
|
||||
#include <NGObjWeb/WEClientCapabilities.h>
|
||||
#include <NGObjWeb/SoObject+SoDAV.h>
|
||||
#include "common.h"
|
||||
|
||||
@interface SOGoObject(Content)
|
||||
- (NSString *)contentAsString;
|
||||
@end
|
||||
|
||||
@implementation SOGoObject
|
||||
|
||||
static BOOL kontactGroupDAV = YES;
|
||||
|
||||
+ (int)version {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ (void)initialize {
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
kontactGroupDAV =
|
||||
[ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"] ? NO : YES;
|
||||
|
||||
/* SoClass security declarations */
|
||||
|
||||
/* require View permission to access the root (bound to authenticated ...) */
|
||||
[[self soClassSecurityInfo] declareObjectProtected:SoPerm_View];
|
||||
|
||||
/* to allow public access to all contained objects (subkeys) */
|
||||
[[self soClassSecurityInfo] setDefaultAccess:@"allow"];
|
||||
|
||||
/* require Authenticated role for View and WebDAV */
|
||||
[[self soClassSecurityInfo] declareRole:SoRole_Authenticated
|
||||
asDefaultForPermission:SoPerm_View];
|
||||
[[self soClassSecurityInfo] declareRole:SoRole_Authenticated
|
||||
asDefaultForPermission:SoPerm_WebDAVAccess];
|
||||
}
|
||||
|
||||
/* containment */
|
||||
|
||||
- (BOOL)doesRetainContainer {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)_name inContainer:(id)_container {
|
||||
if ((self = [super init])) {
|
||||
self->nameInContainer = [_name copy];
|
||||
self->container =
|
||||
[self doesRetainContainer] ? [_container retain] : _container;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (id)init {
|
||||
return [self initWithName:nil inContainer:nil];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
if ([self doesRetainContainer])
|
||||
[self->container release];
|
||||
[self->nameInContainer release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSString *)nameInContainer {
|
||||
return self->nameInContainer;
|
||||
}
|
||||
- (id)container {
|
||||
return self->container;
|
||||
}
|
||||
|
||||
/* ownership */
|
||||
|
||||
- (NSString *)ownerInContext:(id)_ctx {
|
||||
return [[self container] ownerInContext:_ctx];
|
||||
}
|
||||
|
||||
/* hierarchy */
|
||||
|
||||
- (NSArray *)fetchSubfolders {
|
||||
NSMutableArray *ma;
|
||||
NSArray *names;
|
||||
unsigned i, count;
|
||||
|
||||
if ((names = [self toManyRelationshipKeys]) == nil)
|
||||
return nil;
|
||||
|
||||
count = [names count];
|
||||
ma = [NSMutableArray arrayWithCapacity:count + 1];
|
||||
for (i = 0; i < count; i++) {
|
||||
id folder;
|
||||
|
||||
folder = [self lookupName:[names objectAtIndex:i] inContext:nil
|
||||
acquire:NO];
|
||||
if (folder == nil)
|
||||
continue;
|
||||
if ([folder isKindOfClass:[NSException class]])
|
||||
continue;
|
||||
|
||||
[ma addObject:folder];
|
||||
}
|
||||
return ma;
|
||||
}
|
||||
|
||||
/* looking up shared objects */
|
||||
|
||||
- (SOGoUserFolder *)lookupUserFolder {
|
||||
if (![self->container respondsToSelector:_cmd])
|
||||
return nil;
|
||||
|
||||
return [self->container lookupUserFolder];
|
||||
}
|
||||
- (SOGoGroupsFolder *)lookupGroupsFolder {
|
||||
return [[self lookupUserFolder] lookupGroupsFolder];
|
||||
}
|
||||
|
||||
- (void)sleep {
|
||||
if ([self doesRetainContainer])
|
||||
[self->container release];
|
||||
self->container = nil;
|
||||
}
|
||||
|
||||
/* operations */
|
||||
|
||||
- (NSException *)delete {
|
||||
return [NSException exceptionWithHTTPStatus:501 /* not implemented */
|
||||
reason:@"delete not yet implemented, sorry ..."];
|
||||
}
|
||||
|
||||
/* KVC hacks */
|
||||
|
||||
- (id)valueForUndefinedKey:(NSString *)_key {
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* WebDAV */
|
||||
|
||||
- (NSString *)davDisplayName {
|
||||
return [self nameInContainer];
|
||||
}
|
||||
|
||||
/* actions */
|
||||
|
||||
- (id)DELETEAction:(id)_ctx {
|
||||
NSException *error;
|
||||
|
||||
if ((error = [self delete]) != nil)
|
||||
return error;
|
||||
|
||||
/* Note: returning 'nil' breaks in SoObjectRequestHandler */
|
||||
return [NSNumber numberWithBool:YES]; /* delete worked out ... */
|
||||
}
|
||||
|
||||
- (id)GETAction:(id)_ctx {
|
||||
// TODO: I guess this should really be done by SOPE (redirect to
|
||||
// default method)
|
||||
WORequest *rq;
|
||||
WOResponse *r;
|
||||
NSString *uri;
|
||||
|
||||
r = [(WOContext *)_ctx response];
|
||||
rq = [(WOContext *)_ctx request];
|
||||
|
||||
if ([rq isSoWebDAVRequest]) {
|
||||
if ([self respondsToSelector:@selector(contentAsString)]) {
|
||||
NSException *error;
|
||||
id etag;
|
||||
|
||||
if ((error = [self matchesRequestConditionInContext:_ctx]) != nil)
|
||||
return error;
|
||||
|
||||
[r appendContentString:[self contentAsString]];
|
||||
|
||||
if ((etag = [self davEntityTag]) != nil)
|
||||
[r setHeader:etag forKey:@"etag"];
|
||||
return r;
|
||||
}
|
||||
|
||||
return [NSException exceptionWithHTTPStatus:501 /* not implemented */
|
||||
reason:@"no WebDAV GET support?!"];
|
||||
}
|
||||
|
||||
uri = [rq uri];
|
||||
if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
|
||||
uri = [uri stringByAppendingString:@"view"];
|
||||
|
||||
[r setStatus:302 /* moved */];
|
||||
[r setHeader:uri forKey:@"location"];
|
||||
return r;
|
||||
}
|
||||
|
||||
/* etag support */
|
||||
|
||||
- (NSArray *)parseETagList:(NSString *)_c {
|
||||
NSMutableArray *ma;
|
||||
NSArray *etags;
|
||||
unsigned i, count;
|
||||
|
||||
if ([_c length] == 0)
|
||||
return nil;
|
||||
if ([_c isEqualToString:@"*"])
|
||||
return nil;
|
||||
|
||||
etags = [_c componentsSeparatedByString:@","];
|
||||
count = [etags count];
|
||||
ma = [NSMutableArray arrayWithCapacity:count];
|
||||
for (i = 0; i < count; i++) {
|
||||
NSString *etag;
|
||||
|
||||
etag = [[etags objectAtIndex:i] stringByTrimmingSpaces];
|
||||
#if 0 /* this is non-sense, right? */
|
||||
if ([etag hasPrefix:@"\""] && [etag hasSuffix:@"\""])
|
||||
etag = [etag substringWithRange:NSMakeRange(1, [etag length] - 2)];
|
||||
#endif
|
||||
|
||||
if (etag != nil) [ma addObject:etag];
|
||||
}
|
||||
return ma;
|
||||
}
|
||||
|
||||
- (NSException *)checkIfMatchCondition:(NSString *)_c inContext:(id)_ctx {
|
||||
/*
|
||||
Only run the request if one of the etags matches the resource etag,
|
||||
usually used to ensure consistent PUTs.
|
||||
*/
|
||||
NSArray *etags;
|
||||
NSString *etag;
|
||||
|
||||
if ([_c isEqualToString:@"*"])
|
||||
/* to ensure that the resource exists! */
|
||||
return nil;
|
||||
|
||||
if ((etags = [self parseETagList:_c]) == nil)
|
||||
return nil;
|
||||
if ([etags count] == 0) /* no etags to check for? */
|
||||
return nil;
|
||||
|
||||
etag = [self davEntityTag];
|
||||
if ([etag length] == 0) /* has no etag, ignore */
|
||||
return nil;
|
||||
|
||||
if ([etags containsObject:etag]) {
|
||||
[self debugWithFormat:@"etag '%@' matches: %@", etag,
|
||||
[etags componentsJoinedByString:@","]];
|
||||
return nil; /* one etag matches, so continue with request */
|
||||
}
|
||||
|
||||
/* hack for Kontact 3.4 */
|
||||
|
||||
if (kontactGroupDAV) {
|
||||
WEClientCapabilities *cc;
|
||||
|
||||
cc = [[(WOContext *)_ctx request] clientCapabilities];
|
||||
if ([[cc userAgentType] isEqualToString:@"Konqueror"]) {
|
||||
if ([cc majorVersion] == 3 && [cc minorVersion] == 4) {
|
||||
[self logWithFormat:
|
||||
@"WARNING: applying Kontact 3.4 GroupDAV hack"
|
||||
@" - etag check is disabled!"
|
||||
@" (can be enabled using 'ZSDisableKontact34GroupDAVHack')"];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: we might want to return the davEntityTag in the response
|
||||
[self debugWithFormat:@"etag '%@' does not match: %@", etag,
|
||||
[etags componentsJoinedByString:@","]];
|
||||
return [NSException exceptionWithHTTPStatus:412 /* Precondition Failed */
|
||||
reason:@"Precondition Failed"];
|
||||
}
|
||||
|
||||
- (NSException *)checkIfNoneMatchCondition:(NSString *)_c inContext:(id)_ctx {
|
||||
/*
|
||||
If one of the etags is still the same, we can ignore the request.
|
||||
|
||||
Can be used for PUT to ensure that the object does not exist in the store
|
||||
and for GET to retrieve the content only if if the etag changed.
|
||||
*/
|
||||
|
||||
if (![_c isEqualToString:@"*"] &&
|
||||
[[[_ctx request] method] isEqualToString:@"GET"]) {
|
||||
NSString *etag;
|
||||
NSArray *etags;
|
||||
|
||||
if ((etags = [self parseETagList:_c]) == nil)
|
||||
return nil;
|
||||
if ([etags count] == 0) /* no etags to check for? */
|
||||
return nil;
|
||||
|
||||
etag = [self davEntityTag];
|
||||
if ([etag length] == 0) /* has no etag, ignore */
|
||||
return nil;
|
||||
|
||||
if ([etags containsObject:etag]) {
|
||||
[self debugWithFormat:@"etag '%@' matches: %@", etag,
|
||||
[etags componentsJoinedByString:@","]];
|
||||
/* one etag matches, so stop the request */
|
||||
return [NSException exceptionWithHTTPStatus:304 /* Not Modified */
|
||||
reason:@"object was not modified"];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ([_c isEqualToString:@"*"])
|
||||
return nil;
|
||||
|
||||
if ((a = [self parseETagList:_c]) == nil)
|
||||
return nil;
|
||||
#else
|
||||
[self logWithFormat:@"TODO: implement if-none-match for etag: '%@'", _c];
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSException *)matchesRequestConditionInContext:(id)_ctx {
|
||||
NSException *error;
|
||||
WORequest *rq;
|
||||
NSString *c;
|
||||
|
||||
if ((rq = [(WOContext *)_ctx request]) == nil)
|
||||
return nil; /* be tolerant - no request, no condition */
|
||||
|
||||
if ((c = [rq headerForKey:@"if-match"]) != nil) {
|
||||
if ((error = [self checkIfMatchCondition:c inContext:_ctx]) != nil)
|
||||
return error;
|
||||
}
|
||||
if ((c = [rq headerForKey:@"if-none-match"]) != nil) {
|
||||
if ((error = [self checkIfNoneMatchCondition:c inContext:_ctx]) != nil)
|
||||
return error;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* description */
|
||||
|
||||
- (void)appendAttributesToDescription:(NSMutableString *)_ms {
|
||||
if (self->nameInContainer != nil)
|
||||
[_ms appendFormat:@" name=%@", self->nameInContainer];
|
||||
if (self->container != nil) {
|
||||
[_ms appendFormat:@" container=0x%08X/%@",
|
||||
self->container, [self->container valueForKey:@"nameInContainer"]];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
NSMutableString *ms;
|
||||
|
||||
ms = [NSMutableString stringWithCapacity:64];
|
||||
[ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
|
||||
[self appendAttributesToDescription:ms];
|
||||
[ms appendString:@">"];
|
||||
return ms;
|
||||
}
|
||||
|
||||
@end /* SOGoObject */
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright (C) 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 __SOGoUser_H__
|
||||
#define __SOGoUser_H__
|
||||
|
||||
#include <NGObjWeb/SoUser.h>
|
||||
|
||||
/*
|
||||
SOGoUser
|
||||
|
||||
This adds some additional SOGo properties to the SoUser object. The
|
||||
properties are (currently) looked up using the AgenorUserManager.
|
||||
|
||||
You have access to this object from the WOContext:
|
||||
context.activeUser
|
||||
*/
|
||||
|
||||
@class NSString, NSArray, NSDictionary, NSUserDefaults;
|
||||
|
||||
@class NSString, NSArray, NSURL, NSUserDefaults;
|
||||
|
||||
@interface SOGoUser : SoUser
|
||||
{
|
||||
NSString *cn;
|
||||
NSString *email;
|
||||
NSUserDefaults *userDefaults;
|
||||
}
|
||||
|
||||
/* properties */
|
||||
|
||||
- (NSString *)email;
|
||||
- (NSString *)cn;
|
||||
- (NSURL *)freeBusyURL;
|
||||
|
||||
/* shares and identities */
|
||||
|
||||
- (NSString *)primaryIMAP4AccountString;
|
||||
- (NSString *)primaryMailServer;
|
||||
- (NSArray *)additionalIMAP4AccountStrings;
|
||||
- (NSArray *)additionalEMailAddresses;
|
||||
- (NSDictionary *)additionalIMAP4AccountsAndEMails;
|
||||
|
||||
/* defaults */
|
||||
|
||||
- (NSUserDefaults *)userDefaults;
|
||||
|
||||
/* folders */
|
||||
|
||||
- (id)homeFolderInContext:(id)_ctx;
|
||||
- (id)schedulingCalendarInContext:(id)_ctx;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGoUser_H__ */
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
Copyright (C) 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 "SOGoUser.h"
|
||||
#include <SOGo/AgenorUserManager.h>
|
||||
#include "common.h"
|
||||
|
||||
@implementation SOGoUser
|
||||
|
||||
- (void)dealloc {
|
||||
[self->userDefaults release];
|
||||
[self->cn release];
|
||||
[self->email release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* internals */
|
||||
|
||||
- (AgenorUserManager *)userManager {
|
||||
static AgenorUserManager *um = nil;
|
||||
if (um == nil) um = [[AgenorUserManager sharedUserManager] retain];
|
||||
return um;
|
||||
}
|
||||
|
||||
/* properties */
|
||||
|
||||
- (NSString *)email {
|
||||
if (self->email == nil)
|
||||
self->email = [[[self userManager] getEmailForUID:[self login]] copy];
|
||||
return self->email;
|
||||
}
|
||||
|
||||
- (NSString *)cn {
|
||||
if (self->cn == nil)
|
||||
self->cn = [[[self userManager] getCNForUID:[self login]] copy];
|
||||
return self->cn;
|
||||
}
|
||||
|
||||
- (NSString *)primaryIMAP4AccountString {
|
||||
return [[self userManager] getIMAPAccountStringForUID:[self login]];
|
||||
}
|
||||
- (NSString *)primaryMailServer {
|
||||
return [[self userManager] getServerForUID:[self login]];
|
||||
}
|
||||
|
||||
- (NSArray *)additionalIMAP4AccountStrings {
|
||||
return [[self userManager]getSharedMailboxAccountStringsForUID:[self login]];
|
||||
}
|
||||
- (NSArray *)additionalEMailAddresses {
|
||||
return [[self userManager] getSharedMailboxEMailsForUID:[self login]];
|
||||
}
|
||||
|
||||
- (NSDictionary *)additionalIMAP4AccountsAndEMails {
|
||||
return [[self userManager] getSharedMailboxesAndEMailsForUID:[self login]];
|
||||
}
|
||||
|
||||
- (NSURL *)freeBusyURL {
|
||||
return [[self userManager] getFreeBusyURLForUID:[self login]];
|
||||
}
|
||||
|
||||
/* defaults */
|
||||
|
||||
- (NSUserDefaults *)userDefaults {
|
||||
if (self->userDefaults == nil) {
|
||||
self->userDefaults =
|
||||
[[[self userManager] getUserDefaultsForUID:[self login]] retain];
|
||||
}
|
||||
return self->userDefaults;
|
||||
}
|
||||
|
||||
/* folders */
|
||||
|
||||
// TODO: those methods should check whether the traversal stack in the context
|
||||
// already contains proper folders to improve caching behaviour
|
||||
|
||||
- (id)homeFolderInContext:(id)_ctx {
|
||||
/* Note: watch out for cyclic references */
|
||||
// TODO: maybe we should add an [activeUser reset] method to SOPE
|
||||
id folder;
|
||||
|
||||
folder = [(WOContext *)_ctx objectForKey:@"ActiveUserHomeFolder"];
|
||||
if (folder != nil)
|
||||
return [folder isNotNull] ? folder : nil;
|
||||
|
||||
folder = [[WOApplication application] lookupName:[self login]
|
||||
inContext:_ctx acquire:NO];
|
||||
if ([folder isKindOfClass:[NSException class]])
|
||||
return folder;
|
||||
|
||||
[(WOContext *)_ctx setObject:folder ? folder : [NSNull null]
|
||||
forKey:@"ActiveUserHomeFolder"];
|
||||
return folder;
|
||||
}
|
||||
|
||||
- (id)schedulingCalendarInContext:(id)_ctx {
|
||||
/* Note: watch out for cyclic references */
|
||||
id folder;
|
||||
|
||||
folder = [(WOContext *)_ctx objectForKey:@"ActiveUserCalendar"];
|
||||
if (folder != nil)
|
||||
return [folder isNotNull] ? folder : nil;
|
||||
|
||||
folder = [self homeFolderInContext:_ctx];
|
||||
if ([folder isKindOfClass:[NSException class]])
|
||||
return folder;
|
||||
|
||||
folder = [folder lookupName:@"Calendar" inContext:_ctx acquire:NO];
|
||||
if ([folder isKindOfClass:[NSException class]])
|
||||
return folder;
|
||||
|
||||
[(WOContext *)_ctx setObject:folder ? folder : [NSNull null]
|
||||
forKey:@"ActiveUserCalendar"];
|
||||
return folder;
|
||||
}
|
||||
|
||||
@end /* SOGoUser */
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 __SOGo_SOGoUserFolder_H__
|
||||
#define __SOGo_SOGoUserFolder_H__
|
||||
|
||||
#include <SOGo/SOGoFolder.h>
|
||||
|
||||
/*
|
||||
SOGoUserFolder
|
||||
Parent object: the root object (SoApplication object)
|
||||
Child objects:
|
||||
'Groups': SOGoGroupsFolder
|
||||
'Calendar': SOGoAppointmentFolder
|
||||
|
||||
The SOGoUserFolder is the "home directory" of the user where all his
|
||||
processing starts. It is the 'znek' in such a path:
|
||||
/SOGo/so/znek/Calendar
|
||||
*/
|
||||
|
||||
@class NSString;
|
||||
|
||||
@interface SOGoUserFolder : SOGoFolder
|
||||
{
|
||||
}
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSString *)login;
|
||||
|
||||
/* ownership */
|
||||
|
||||
- (NSString *)ownerInContext:(id)_ctx;
|
||||
|
||||
/* pathes */
|
||||
|
||||
- (NSString *)ocsUserPath;
|
||||
- (NSString *)ocsPrivateCalendarPath;
|
||||
|
||||
- (id)lookupFreeBusyObject;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_SOGoUserFolder_H__ */
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
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 "SOGoUserFolder.h"
|
||||
#include "WOContext+Agenor.h"
|
||||
#include "common.h"
|
||||
|
||||
@implementation SOGoUserFolder
|
||||
|
||||
/* accessors */
|
||||
|
||||
- (NSString *)login {
|
||||
return [self nameInContainer];
|
||||
}
|
||||
|
||||
/* hierarchy */
|
||||
|
||||
- (NSArray *)toManyRelationshipKeys {
|
||||
static NSArray *children = nil;
|
||||
|
||||
if (children == nil) {
|
||||
children = [[NSArray alloc] initWithObjects:
|
||||
@"Calendar", @"Contacts", @"Mail", nil];
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
/* ownership */
|
||||
|
||||
- (NSString *)ownerInContext:(id)_ctx {
|
||||
return [self login];
|
||||
}
|
||||
|
||||
/* looking up shared objects */
|
||||
|
||||
- (SOGoUserFolder *)lookupUserFolder {
|
||||
return self;
|
||||
}
|
||||
- (SOGoGroupsFolder *)lookupGroupsFolder {
|
||||
return [self lookupName:@"Groups" inContext:nil acquire:NO];
|
||||
}
|
||||
|
||||
/* pathes */
|
||||
|
||||
- (void)setOCSPath:(NSString *)_path {
|
||||
[self warnWithFormat:
|
||||
@"rejected attempt to reset user-folder path: '%@'", _path];
|
||||
}
|
||||
- (NSString *)ocsPath {
|
||||
return [@"/Users/" stringByAppendingString:[self login]];
|
||||
}
|
||||
|
||||
- (NSString *)ocsUserPath {
|
||||
return [self ocsPath];
|
||||
}
|
||||
- (NSString *)ocsPrivateCalendarPath {
|
||||
return [[self ocsUserPath] stringByAppendingString:@"/Calendar"];
|
||||
}
|
||||
- (NSString *)ocsPrivateContactsPath {
|
||||
return [[self ocsUserPath] stringByAppendingString:@"/Contacts"];
|
||||
}
|
||||
|
||||
/* name lookup */
|
||||
|
||||
- (id)privateCalendar:(NSString *)_key inContext:(id)_ctx {
|
||||
static Class calClass = Nil;
|
||||
id calendar;
|
||||
|
||||
if (calClass == Nil)
|
||||
calClass = NSClassFromString(@"SOGoAppointmentFolder");
|
||||
if (calClass == Nil) {
|
||||
[self errorWithFormat:@"missing SOGoAppointmentFolder class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
calendar = [[calClass alloc] initWithName:_key inContainer:self];
|
||||
[calendar setOCSPath:[self ocsPrivateCalendarPath]];
|
||||
return [calendar autorelease];
|
||||
}
|
||||
|
||||
- (id)privateContacts:(NSString *)_key inContext:(id)_ctx {
|
||||
static Class calClass = Nil;
|
||||
id calendar;
|
||||
|
||||
if (calClass == Nil)
|
||||
calClass = NSClassFromString(@"SOGoContactFolder");
|
||||
if (calClass == Nil) {
|
||||
[self errorWithFormat:@"missing SOGoContactFolder class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
calendar = [[calClass alloc] initWithName:_key inContainer:self];
|
||||
[calendar setOCSPath:[self ocsPrivateContactsPath]];
|
||||
return [calendar autorelease];
|
||||
}
|
||||
|
||||
- (id)groupsFolder:(NSString *)_key inContext:(id)_ctx {
|
||||
static Class fldClass = Nil;
|
||||
id folder;
|
||||
|
||||
if (fldClass == Nil)
|
||||
fldClass = NSClassFromString(@"SOGoGroupsFolder");
|
||||
if (fldClass == Nil) {
|
||||
[self errorWithFormat:@"missing SOGoGroupsFolder class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
folder = [[fldClass alloc] initWithName:_key inContainer:self];
|
||||
return [folder autorelease];
|
||||
}
|
||||
|
||||
- (id)mailAccountsFolder:(NSString *)_key inContext:(id)_ctx {
|
||||
static Class fldClass = Nil;
|
||||
id folder;
|
||||
|
||||
if (fldClass == Nil)
|
||||
fldClass = NSClassFromString(@"SOGoMailAccounts");
|
||||
if (fldClass == Nil) {
|
||||
[self errorWithFormat:@"missing SOGoMailAccounts class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
folder = [[fldClass alloc] initWithName:_key inContainer:self];
|
||||
return [folder autorelease];
|
||||
}
|
||||
|
||||
- (id)freeBusyObject:(NSString *)_key inContext:(id)_ctx {
|
||||
static Class fbClass = Nil;
|
||||
id fb;
|
||||
|
||||
if (fbClass == Nil)
|
||||
fbClass = NSClassFromString(@"SOGoFreeBusyObject");
|
||||
if (fbClass == Nil) {
|
||||
[self errorWithFormat:@"missing SOGoFreeBusyObject class!"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
fb = [[fbClass alloc] initWithName:_key inContainer:self];
|
||||
return [fb autorelease];
|
||||
}
|
||||
|
||||
- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
|
||||
id obj;
|
||||
|
||||
/* first check attributes directly bound to the application */
|
||||
if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
|
||||
return obj;
|
||||
|
||||
if ([_key hasPrefix:@"Calendar"]) {
|
||||
id calendar;
|
||||
|
||||
calendar = [self privateCalendar:@"Calendar" inContext:_ctx];
|
||||
if ([_key isEqualToString:@"Calendar"])
|
||||
return calendar;
|
||||
|
||||
return [calendar lookupName:[_key pathExtension]
|
||||
inContext:_ctx acquire:NO];
|
||||
}
|
||||
|
||||
if ([_key isEqualToString:@"Contacts"])
|
||||
return [self privateContacts:_key inContext:_ctx];
|
||||
|
||||
if ([_key isEqualToString:@"Groups"]) {
|
||||
/* Agenor requirement, return 403 to stop acquisition */
|
||||
if (![_ctx isAccessFromIntranet]) {
|
||||
return [NSException exceptionWithHTTPStatus:403 /* Forbidden */];
|
||||
}
|
||||
return [self groupsFolder:_key inContext:_ctx];
|
||||
}
|
||||
|
||||
if ([_key isEqualToString:@"Mail"])
|
||||
return [self mailAccountsFolder:_key inContext:_ctx];
|
||||
|
||||
if ([_key isEqualToString:@"freebusy.ifb"])
|
||||
return [self freeBusyObject:_key inContext:_ctx];
|
||||
|
||||
/* return 404 to stop acquisition */
|
||||
return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
|
||||
}
|
||||
|
||||
/* WebDAV */
|
||||
|
||||
- (NSArray *)fetchContentObjectNames {
|
||||
static NSArray *cos = nil;
|
||||
|
||||
if (!cos) {
|
||||
cos = [[NSArray alloc] initWithObjects:@"freebusy.ifb", nil];
|
||||
}
|
||||
return cos;
|
||||
}
|
||||
|
||||
- (BOOL)davIsCollection {
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end /* SOGoUserFolder */
|
||||
@@ -0,0 +1,9 @@
|
||||
# version file
|
||||
|
||||
SUBMINOR_VERSION:=70
|
||||
|
||||
# v0.9.63 requires libNGiCal v4.5.54
|
||||
# v0.9.60 requires libNGiCal v4.5.49
|
||||
# v0.9.50 requires libGDLContentStore v4.5.30
|
||||
# v0.9.34 requires libGDLContentStore v4.5.26
|
||||
# v0.9.26 requires libOGoContentStore v0.9.13
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (C) 2000-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 __SOGo_WOContext_Agenor_H_
|
||||
#define __SOGo_WOContext_Agenor_H_
|
||||
|
||||
#include <NGObjWeb/WOContext.h>
|
||||
|
||||
@interface WOContext (Agenor)
|
||||
|
||||
- (BOOL)isAccessFromIntranet;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __SOGo_WOContext_Agenor_H_ */
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright (C) 2000-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 "WOContext+Agenor.h"
|
||||
#include "common.h"
|
||||
|
||||
@implementation WOContext(Agenor)
|
||||
|
||||
static EOQualifier *internetDetectQualifier = nil;
|
||||
|
||||
static EOQualifier *getInternetDetectQualifier(void) {
|
||||
static BOOL didCheck = NO;
|
||||
NSUserDefaults *ud;
|
||||
NSString *s;
|
||||
|
||||
if (didCheck) return internetDetectQualifier;
|
||||
|
||||
ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
if ((s = [ud stringForKey:@"SOGoInternetDetectQualifier"]) != nil) {
|
||||
internetDetectQualifier =
|
||||
[[EOQualifier qualifierWithQualifierFormat:s] retain];
|
||||
if (internetDetectQualifier == nil)
|
||||
NSLog(@"ERROR: could not parse qualifier: '%@'", s);
|
||||
}
|
||||
if (internetDetectQualifier == nil)
|
||||
NSLog(@"Note: no 'SOGoInternetDetectQualifier' configured.");
|
||||
else {
|
||||
NSLog(@"Note: detect Internet access using: %@",
|
||||
internetDetectQualifier);
|
||||
}
|
||||
|
||||
didCheck = YES;
|
||||
return internetDetectQualifier;
|
||||
}
|
||||
|
||||
- (BOOL)isAccessFromIntranet {
|
||||
id<EOQualifierEvaluation> q;
|
||||
NSNumber *bv;
|
||||
WORequest *rq;
|
||||
BOOL ok;
|
||||
|
||||
if ((bv = [self objectForKey:@"_agenorUnrestricedAccess"]) != nil)
|
||||
return [bv boolValue];
|
||||
|
||||
if ((rq = [self request]) == nil) {
|
||||
[self logWithFormat:@"ERROR: got no request for context!"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
if ((q = (id)getInternetDetectQualifier()) == nil)
|
||||
/* if no qualifier is set, allow access */
|
||||
ok = YES;
|
||||
else
|
||||
/* is Internet request? */
|
||||
ok = [q evaluateWithObject:[rq headers]] ? NO : YES;
|
||||
|
||||
bv = [NSNumber numberWithBool:ok];
|
||||
[self setObject:bv forKey:@"_agenorUnrestricedAccess"];
|
||||
return ok;
|
||||
}
|
||||
|
||||
@end /* WOContext(Agenor) */
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
Copyright (C) 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 "AgenorUserManager.h"
|
||||
#include "common.h"
|
||||
|
||||
static void usage(NSArray *args) {
|
||||
fprintf(stderr, "usage: %s <uid> read|write|info [<key>] [<value>]\n",
|
||||
[[args objectAtIndex:0] cString]);
|
||||
}
|
||||
|
||||
static void doInfo(NSUserDefaults *defaults) {
|
||||
printf("defaults for: '%s'\n", [[defaults valueForKey:@"uid"] cString]);
|
||||
printf(" profile table: '%s'\n",
|
||||
[[[defaults valueForKey:@"tableURL"] absoluteString] cString]);
|
||||
}
|
||||
|
||||
static void doRead(NSUserDefaults *defaults, NSString *key) {
|
||||
id value;
|
||||
|
||||
if (key == nil) {
|
||||
NSArray *defNames;
|
||||
unsigned i, count;
|
||||
|
||||
defNames = [defaults valueForKey:@"primaryDefaultNames"];
|
||||
if ((count = [defNames count]) == 0) {
|
||||
fprintf(stderr, "There are no keys in the Agenor profile!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
printf("%s: %s\n",
|
||||
[[defNames objectAtIndex:i] cString],
|
||||
[[[defaults objectForKey:[defNames objectAtIndex:i]]
|
||||
description] cString]);
|
||||
}
|
||||
}
|
||||
else if ((value = [defaults objectForKey:key]) == nil) {
|
||||
fprintf(stderr, "There is no key '%s' in the Agenor profile!\n",
|
||||
[key cString]);
|
||||
}
|
||||
else
|
||||
printf("%s\n", [[value description] cString]);
|
||||
}
|
||||
|
||||
static void doWrite(NSUserDefaults *defaults, NSString *key, NSString *value) {
|
||||
[defaults setObject:value forKey:key];
|
||||
|
||||
if (![defaults synchronize]) {
|
||||
fprintf(stderr, "Failed to synchronize defaults with profile!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void doIt(NSArray *args) {
|
||||
AgenorUserManager *userManager;
|
||||
NSUserDefaults *defaults;
|
||||
NSString *uid, *op, *key, *value;
|
||||
|
||||
/* extract arguments */
|
||||
|
||||
if ([args count] < 3) {
|
||||
usage(args);
|
||||
return;
|
||||
}
|
||||
|
||||
uid = [args objectAtIndex:1];
|
||||
op = [args objectAtIndex:2];
|
||||
key = nil;
|
||||
value = nil;
|
||||
|
||||
if ([args count] > 3)
|
||||
key = [args objectAtIndex:3];
|
||||
|
||||
if ([op isEqualToString:@"write"]) {
|
||||
if ([args count] < 5) {
|
||||
usage(args);
|
||||
return;
|
||||
}
|
||||
value = [args objectAtIndex:4];
|
||||
}
|
||||
|
||||
/* run */
|
||||
|
||||
userManager = [AgenorUserManager sharedUserManager];
|
||||
defaults = [userManager getUserDefaultsForUID:uid];
|
||||
|
||||
if (![defaults isNotNull]) {
|
||||
fprintf(stderr, "Error: found no userdefaults for UID: '%s'\n",
|
||||
[uid cString]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ([op isEqualToString:@"read"])
|
||||
doRead(defaults, key);
|
||||
else if ([op isEqualToString:@"write"])
|
||||
doWrite(defaults, key, value);
|
||||
else if ([op isEqualToString:@"info"])
|
||||
doInfo(defaults);
|
||||
else
|
||||
usage(args);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
#if LIB_FOUNDATION_LIBRARY
|
||||
[NSProcessInfo initializeWithArguments:argv count:argc environment:env];
|
||||
#endif
|
||||
|
||||
doIt([[NSProcessInfo processInfo] argumentsWithoutDefaults]);
|
||||
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright (C) 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 "AgenorUserManager.h"
|
||||
#include "common.h"
|
||||
|
||||
static void usage(NSArray *args) {
|
||||
fprintf(stderr, "usage: %s <email1> <email2> <email3>\n",
|
||||
[[args objectAtIndex:0] cString]);
|
||||
}
|
||||
|
||||
static void doIt(NSArray *args) {
|
||||
AgenorUserManager *userManager;
|
||||
NSEnumerator *e;
|
||||
NSString *email;
|
||||
|
||||
if ([args count] < 2) {
|
||||
usage(args);
|
||||
return;
|
||||
}
|
||||
|
||||
userManager = [AgenorUserManager sharedUserManager];
|
||||
|
||||
e = [args objectEnumerator];
|
||||
[e nextObject]; /* consume the command name */
|
||||
|
||||
while ((email = [e nextObject]) != nil) {
|
||||
NSString *uid;
|
||||
|
||||
uid = [userManager getUIDForEmail:email];
|
||||
|
||||
if ([uid isNotNull])
|
||||
printf("%s: %s\n", [email cString], [uid cString]);
|
||||
else {
|
||||
fprintf(stderr, "ERROR: did not find uid for email: '%s'\n",
|
||||
[email cString]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
#if LIB_FOUNDATION_LIBRARY
|
||||
[NSProcessInfo initializeWithArguments:argv count:argc environment:env];
|
||||
#endif
|
||||
|
||||
doIt([[NSProcessInfo processInfo] argumentsWithoutDefaults]);
|
||||
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright (C) 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 "AgenorUserManager.h"
|
||||
#include "common.h"
|
||||
|
||||
static void usage(NSArray *args) {
|
||||
fprintf(stderr, "usage: %s <uid1> <uid2> <uid3>\n",
|
||||
[[args objectAtIndex:0] cString]);
|
||||
}
|
||||
|
||||
static void handleUID(NSString *uid, AgenorUserManager *userManager) {
|
||||
NSArray *emails;
|
||||
NSString *primary;
|
||||
unsigned i, count;
|
||||
|
||||
primary = [userManager getEmailForUID:uid];
|
||||
emails = [userManager getSharedMailboxEMailsForUID:uid];
|
||||
|
||||
printf("%s:", [uid cString]);
|
||||
|
||||
if ([primary length] > 0)
|
||||
printf(" %s\n", [primary cString]);
|
||||
else
|
||||
printf(" <no primary email found>\n");
|
||||
|
||||
if ((count = [emails count]) == 0) {
|
||||
printf(" <no shares with emitter access>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
printf(" %s\n", [[emails objectAtIndex:i] cString]);
|
||||
}
|
||||
|
||||
static void doIt(NSArray *args) {
|
||||
AgenorUserManager *userManager;
|
||||
NSEnumerator *e;
|
||||
NSString *uid;
|
||||
|
||||
if ([args count] < 2) {
|
||||
usage(args);
|
||||
return;
|
||||
}
|
||||
|
||||
userManager = [AgenorUserManager sharedUserManager];
|
||||
|
||||
e = [args objectEnumerator];
|
||||
[e nextObject]; /* consume the command name */
|
||||
|
||||
while ((uid = [e nextObject]) != nil)
|
||||
handleUID(uid, userManager);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
#if LIB_FOUNDATION_LIBRARY
|
||||
[NSProcessInfo initializeWithArguments:argv count:argc environment:env];
|
||||
#endif
|
||||
|
||||
doIt([[NSProcessInfo processInfo] argumentsWithoutDefaults]);
|
||||
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright (C) 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 "AgenorUserManager.h"
|
||||
#include "common.h"
|
||||
|
||||
static void usage(NSArray *args) {
|
||||
fprintf(stderr, "usage: %s <uid1> <uid2> <uid3>\n",
|
||||
[[args objectAtIndex:0] cString]);
|
||||
}
|
||||
|
||||
static void handleUID(NSString *uid, AgenorUserManager *userManager) {
|
||||
NSArray *shares;
|
||||
unsigned i, count;
|
||||
|
||||
shares = [userManager getSharedMailboxAccountStringsForUID:uid];
|
||||
|
||||
printf("%s:", [uid cString]);
|
||||
|
||||
if ((count = [shares count]) == 0) {
|
||||
printf(" <no shares>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
puts("");
|
||||
for (i = 0; i < count; i++)
|
||||
printf(" %s\n", [[shares objectAtIndex:i] cString]);
|
||||
}
|
||||
|
||||
static void doIt(NSArray *args) {
|
||||
AgenorUserManager *userManager;
|
||||
NSEnumerator *e;
|
||||
NSString *uid;
|
||||
|
||||
if ([args count] < 2) {
|
||||
usage(args);
|
||||
return;
|
||||
}
|
||||
|
||||
userManager = [AgenorUserManager sharedUserManager];
|
||||
|
||||
e = [args objectEnumerator];
|
||||
[e nextObject]; /* consume the command name */
|
||||
|
||||
while ((uid = [e nextObject]) != nil)
|
||||
handleUID(uid, userManager);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
#if LIB_FOUNDATION_LIBRARY
|
||||
[NSProcessInfo initializeWithArguments:argv count:argc environment:env];
|
||||
#endif
|
||||
|
||||
doIt([[NSProcessInfo processInfo] argumentsWithoutDefaults]);
|
||||
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (C) 2002-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: common.h 96 2004-06-30 08:35:34Z helge $
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
|
||||
# include <NGExtensions/NGObjectMacros.h>
|
||||
# include <NGExtensions/NSString+Ext.h>
|
||||
#endif
|
||||
|
||||
#include <NGExtensions/NGExtensions.h>
|
||||
#include <NGObjWeb/NGObjWeb.h>
|
||||
#include <NGObjWeb/SoObjects.h>
|
||||
Reference in New Issue
Block a user