#import <NGExtensions/NSNull+misc.h>
#import <NGImap4/NGImap4Connection.h>
+#import <SoObjects/SOGo/NSArray+Utilities.h>
+#import <SoObjects/SOGo/SOGoUser.h>
+
+#import "SOGoDraftsFolder.h"
#import "SOGoMailFolder.h"
#import "SOGoMailManager.h"
-#import "SOGoDraftsFolder.h"
-#import "SOGoUser+Mail.h"
+#import "SOGoSentFolder.h"
+#import "SOGoTrashFolder.h"
#import "SOGoMailAccount.h"
@implementation SOGoMailAccount
-static NSArray *rootFolderNames = nil;
-static NSString *inboxFolderName = @"INBOX";
-static NSString *draftsFolderName = @"Drafts";
-static NSString *sieveFolderName = @"Filters";
+static NSArray *rootFolderNames = nil;
+static NSString *inboxFolderName = @"INBOX";
+static NSString *draftsFolderName = @"Drafts";
+static NSString *sieveFolderName = @"Filters";
static NSString *sentFolderName = nil;
static NSString *trashFolderName = nil;
-static NSString *sharedFolderName = @""; // TODO: add English default
+static NSString *sharedFolderName = @""; // TODO: add English default
static NSString *otherUsersFolderName = @""; // TODO: add English default
-static BOOL useAltNamespace = NO;
-+ (void)initialize {
++ (void) initialize
+{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *cfgDraftsFolderName;
- useAltNamespace = [ud boolForKey:@"SOGoSpecialFoldersInRoot"];
-
sharedFolderName = [ud stringForKey:@"SOGoSharedFolderName"];
otherUsersFolderName = [ud stringForKey:@"SOGoOtherUsersFolderName"];
cfgDraftsFolderName = [ud stringForKey:@"SOGoDraftsFolderName"];
NSLog(@"Note: using shared-folders name: '%@'", sharedFolderName);
NSLog(@"Note: using other-users-folders name: '%@'", otherUsersFolderName);
- if ([ud boolForKey:@"SOGoEnableSieveFolder"]) {
+ if ([ud boolForKey: @"SOGoEnableSieveFolder"])
rootFolderNames = [[NSArray alloc] initWithObjects:
draftsFolderName,
sieveFolderName,
nil];
- }
- else {
+ else
rootFolderNames = [[NSArray alloc] initWithObjects:
draftsFolderName,
nil];
- }
+}
+
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ inboxFolder = nil;
+ draftsFolder = nil;
+ sentFolder = nil;
+ trashFolder = nil;
+ }
+
+ return self;
+}
+
+- (void) dealloc
+{
+ [inboxFolder release];
+ [draftsFolder release];
+ [sentFolder release];
+ [trashFolder release];
+ [super dealloc];
}
/* shared accounts */
-- (BOOL)isSharedAccount {
+- (BOOL) isSharedAccount
+{
NSString *s;
NSRange r;
return [s rangeOfString:@".-."].length > 0 ? YES : NO;
}
-- (NSString *)sharedAccountName {
+- (NSString *) sharedAccountName
+{
return nil;
}
/* listing the available folders */
-- (NSArray *)additionalRootFolderNames {
+- (NSArray *) additionalRootFolderNames
+{
return rootFolderNames;
}
+- (BOOL) isInDraftsFolder
+{
+ return NO;
+}
+
- (NSArray *) toManyRelationshipKeys
{
NSMutableArray *folders;
NSArray *imapFolders, *additionalFolders;
- folders = [NSMutableArray new];
- [folders autorelease];
+ folders = [NSMutableArray array];
imapFolders = [[self imap4Connection] subfoldersForURL: [self imap4URL]];
additionalFolders = [self additionalRootFolderNames];
[folders removeObjectsInArray: additionalFolders];
[folders addObjectsFromArray: additionalFolders];
}
-
+
return folders;
}
-/* identity */
-
-- (SOGoMailIdentity *)preferredIdentity {
- return [[context activeUser] primaryMailIdentityForAccount:
- [self nameInContainer]];
-}
-
/* hierarchy */
-- (SOGoMailAccount *)mailAccountFolder {
+- (SOGoMailAccount *) mailAccountFolder
+{
return self;
}
- (NSArray *) allFolderPaths
{
- NSMutableArray *newFolders;
+ NSMutableArray *folderPaths;
NSArray *rawFolders, *mainFolders;
- rawFolders = [[self imap4Connection]
- allFoldersForURL: [self imap4URL]];
+ rawFolders = [[self imap4Connection] allFoldersForURL: [self imap4URL]];
- mainFolders = [NSArray arrayWithObjects: inboxFolderName, draftsFolderName,
- sentFolder, trashFolder, nil];
- newFolders = [NSMutableArray arrayWithArray: rawFolders];
- [newFolders removeObjectsInArray: mainFolders];
- [newFolders sortUsingSelector: @selector (caseInsensitiveCompare:)];
- [newFolders replaceObjectsInRange: NSMakeRange (0, 0)
- withObjectsFromArray: mainFolders];
+ mainFolders = [[NSArray arrayWithObjects:
+ [self inboxFolderNameInContext: context],
+ [self draftsFolderNameInContext: context],
+ [self sentFolderNameInContext: context],
+ [self trashFolderNameInContext: context],
+ nil] stringsWithFormat: @"/%@"];
+ folderPaths = [NSMutableArray arrayWithArray: rawFolders];
+ [folderPaths removeObjectsInArray: mainFolders];
+ [folderPaths
+ sortUsingSelector: @selector (localizedCaseInsensitiveCompare:)];
+ [folderPaths replaceObjectsInRange: NSMakeRange (0, 0)
+ withObjectsFromArray: mainFolders];
- return newFolders;
+ return folderPaths;
}
/* IMAP4 */
-- (BOOL)useSSL {
+- (BOOL) useSSL
+{
return NO;
}
-- (NSString *)imap4LoginFromHTTP {
+- (NSString *) imap4LoginFromHTTP
+{
WORequest *rq;
NSString *s;
NSArray *creds;
return urlString;
}
-- (NSString *) imap4Login
+- (NSMutableString *) traversalFromMailAccount
{
- return [[self imap4URL] user];
+ return [NSMutableString string];
}
-/* name lookup */
-
-- (id)lookupFolder:(NSString *)_key ofClassNamed:(NSString *)_cn
- inContext:(id)_cx
+- (NSString *) imap4Login
{
- Class clazz;
-
- if ((clazz = NSClassFromString(_cn)) == Nil) {
- [self logWithFormat:@"ERROR: did not find class '%@' for key: '%@'",
- _cn, _key];
- return [NSException exceptionWithHTTPStatus:500 /* server error */
- reason:@"did not find mail folder class!"];
- }
- return [[[clazz alloc] initWithName:_key inContainer:self] autorelease];
-}
-
-- (id)lookupImap4Folder:(NSString *)_key inContext:(id)_cx {
- NSString *s;
-
- s = [_key isEqualToString: [self trashFolderNameInContext:_cx]]
- ? @"SOGoTrashFolder" : @"SOGoMailFolder";
-
- return [self lookupFolder:_key ofClassNamed:s inContext:_cx];
+ return [[self imap4URL] user];
}
-- (id)lookupDraftsFolder:(NSString *)_key inContext:(id)_ctx {
- return [self lookupFolder:_key ofClassNamed:@"SOGoDraftsFolder"
- inContext:_ctx];
-}
-- (id)lookupFiltersFolder:(NSString *)_key inContext:(id)_ctx {
- return [self lookupFolder:_key ofClassNamed:@"SOGoSieveScriptsFolder"
- inContext:_ctx];
-}
+/* name lookup */
- (id) lookupName: (NSString *) _key
inContext: (id)_ctx
acquire: (BOOL) _flag
{
+ NSString *folderName;
+ Class klazz;
id obj;
if ([_key hasPrefix: @"folder"])
{
- // TODO: those should be product.plist bindings? (can't be class bindings
- // though because they are 'per-account')
- if ([_key isEqualToString: [self draftsFolderNameInContext: _ctx]])
- obj = [self lookupDraftsFolder: _key inContext: _ctx];
- else if ([_key isEqualToString: [self sieveFolderNameInContext: _ctx]])
- obj = [self lookupFiltersFolder: _key inContext: _ctx];
+ folderName = [_key substringFromIndex: 6];
+ if ([folderName
+ isEqualToString: [self sentFolderNameInContext: _ctx]])
+ klazz = [SOGoSentFolder class];
+ else if ([folderName
+ isEqualToString: [self draftsFolderNameInContext: _ctx]])
+ klazz = [SOGoDraftsFolder class];
+ else if ([folderName
+ isEqualToString: [self trashFolderNameInContext: _ctx]])
+ klazz = [SOGoTrashFolder class];
+/* else if ([folderName isEqualToString: [self sieveFolderNameInContext: _ctx]])
+ obj = [self lookupFiltersFolder: _key inContext: _ctx]; */
else
- obj = [self lookupImap4Folder: _key inContext: _ctx];
+ klazz = [SOGoMailFolder class];
+
+ obj = [klazz objectWithName: _key inContainer: self];
}
else
obj = [super lookupName: _key inContext: _ctx acquire: NO];
- (NSString *) inboxFolderNameInContext: (id)_ctx
{
/* cannot be changed in Cyrus ? */
- return [NSString stringWithFormat: @"folder%@", inboxFolderName];
+ return inboxFolderName;
}
-- (NSString *) draftsFolderNameInContext: (id) _ctx
+- (NSString *) _userFolderNameWithPurpose: (NSString *) purpose
{
- /* SOGo managed folder */
- return [NSString stringWithFormat: @"folder%@", draftsFolderName];
+ NSUserDefaults *ud;
+ NSMutableDictionary *mailSettings;
+ NSString *folderName;
+
+ folderName = nil;
+ ud = [[context activeUser] userSettings];
+ mailSettings = [ud objectForKey: @"Mail"];
+ if (mailSettings)
+ folderName
+ = [mailSettings objectForKey: [NSString stringWithFormat: @"%@Folder",
+ purpose]];
+
+ return folderName;
}
-- (NSString *) sieveFolderNameInContext: (id) _ctx
+- (NSString *) draftsFolderNameInContext: (id) _ctx
{
- return [NSString stringWithFormat: @"folder%@", sieveFolderName];
+ NSString *folderName;
+
+ folderName = [self _userFolderNameWithPurpose: @"Drafts"];
+ if (!folderName)
+ folderName = draftsFolderName;
+
+ return folderName;
}
+// - (NSString *) sieveFolderNameInContext: (id) _ctx
+// {
+// return sieveFolderName;
+// }
+
- (NSString *) sentFolderNameInContext: (id)_ctx
{
- return [NSString stringWithFormat: @"folder%@", sentFolderName];
+ NSString *folderName;
+
+ folderName = [self _userFolderNameWithPurpose: @"Sent"];
+ if (!folderName)
+ folderName = sentFolderName;
+
+ return folderName;
}
- (NSString *) trashFolderNameInContext: (id)_ctx
{
- return [NSString stringWithFormat: @"folder%@", trashFolderName];
+ NSString *folderName;
+
+ folderName = [self _userFolderNameWithPurpose: @"Trash"];
+ if (!folderName)
+ folderName = trashFolderName;
+
+ return folderName;
+}
+
+- (id) folderWithTraversal: (NSString *) traversal
+ andClassName: (NSString *) className
+{
+ NSArray *paths;
+ NSString *currentName;
+ id currentContainer;
+ unsigned int count, max;
+ Class clazz;
+
+ currentContainer = self;
+ paths = [traversal componentsSeparatedByString: @"/"];
+
+ if (!className)
+ clazz = [SOGoMailFolder class];
+ else
+ clazz = NSClassFromString (className);
+
+ max = [paths count];
+ for (count = 0; count < max - 1; count++)
+ {
+ currentName = [NSString stringWithFormat: @"folder%@",
+ [paths objectAtIndex: count]];
+ currentContainer = [SOGoMailFolder objectWithName: currentName
+ inContainer: currentContainer];
+ }
+ currentName = [NSString stringWithFormat: @"folder%@",
+ [paths objectAtIndex: max - 1]];
+
+ return [clazz objectWithName: currentName inContainer: currentContainer];
}
- (SOGoMailFolder *) inboxFolderInContext: (id) _ctx
// TODO: use some profile to determine real location, use a -traverse lookup
if (!inboxFolder)
{
- inboxFolder = [self lookupName: [self inboxFolderNameInContext: _ctx]
- inContext: _ctx acquire: NO];
+ inboxFolder
+ = [self folderWithTraversal: [self inboxFolderNameInContext: _ctx]
+ andClassName: nil];
[inboxFolder retain];
}
return inboxFolder;
}
-- (SOGoMailFolder *) sentFolderInContext: (id) _ctx
+- (SOGoDraftsFolder *) draftsFolderInContext: (id) _ctx
+{
+ // TODO: use some profile to determine real location, use a -traverse lookup
+
+ if (!draftsFolder)
+ {
+ draftsFolder
+ = [self folderWithTraversal: [self draftsFolderNameInContext: _ctx]
+ andClassName: @"SOGoDraftsFolder"];
+ [draftsFolder retain];
+ }
+
+ return draftsFolder;
+}
+
+- (SOGoSentFolder *) sentFolderInContext: (id) _ctx
{
- SOGoMailFolder *lookupFolder;
// TODO: use some profile to determine real location, use a -traverse lookup
if (!sentFolder)
{
- lookupFolder = (useAltNamespace
- ? (id) self
- : [self inboxFolderInContext:_ctx]);
- if (![lookupFolder isKindOfClass: [NSException class]])
- sentFolder = [lookupFolder lookupName: [self sentFolderNameInContext:_ctx]
- inContext: _ctx acquire: NO];
- if (![sentFolder isNotNull])
- sentFolder = [NSException exceptionWithHTTPStatus: 404 /* not found */
- reason: @"did not find Sent folder!"];
+ sentFolder
+ = [self folderWithTraversal: [self sentFolderNameInContext: _ctx]
+ andClassName: @"SOGoSentFolder"];
[sentFolder retain];
}
return sentFolder;
}
-- (SOGoMailFolder *) trashFolderInContext: (id) _ctx
+- (SOGoTrashFolder *) trashFolderInContext: (id) _ctx
{
- SOGoMailFolder *lookupFolder;
- // TODO: use some profile to determine real location, use a -traverse lookup
-
if (!trashFolder)
{
- lookupFolder = (useAltNamespace
- ? (id) self
- : [self inboxFolderInContext:_ctx]);
- if (![lookupFolder isKindOfClass: [NSException class]])
- trashFolder = [lookupFolder lookupName: [self trashFolderNameInContext: _ctx]
- inContext: _ctx acquire: NO];
- if (![trashFolder isNotNull])
- trashFolder = [NSException exceptionWithHTTPStatus: 404 /* not found */
- reason: @"did not find Trash folder!"];
+ trashFolder
+ = [self folderWithTraversal: [self trashFolderNameInContext: _ctx]
+ andClassName: @"SOGoTrashFolder"];
[trashFolder retain];
}
s = [self nameInContainer];
r = [s rangeOfString:@"@"];
- if (r.length > 0) {
- login = [s substringToIndex:r.location];
- host = [s substringFromIndex:(r.location + r.length)];
- }
- else {
- login = nil;
- host = s;
- }
+ if (r.length > 0)
+ {
+ login = [s substringToIndex:r.location];
+ host = [s substringFromIndex:(r.location + r.length)];
+ }
+ else
+ {
+ login = nil;
+ host = s;
+ }
r = [host rangeOfString:@"."];
if (r.length > 0)