2 Copyright (C) 2004-2005 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #import <Foundation/NSArray.h>
24 #import <NGObjWeb/NSException+HTTP.h>
25 #import <NGExtensions/NSNull+misc.h>
26 #import <NGImap4/NGImap4Connection.h>
27 #import <NGImap4/NGImap4ConnectionManager.h>
29 #import "SOGoMailManager.h"
32 Could check read-write state:
33 dict = [[self->context client] select:[self absoluteName]];
35 [[dict objectForKey:@"access"] isEqualToString:@"READ-WRITE"]
36 ? NoNumber : YesNumber;
38 TODO: to implement copy, use "uid copy" instead of "copy" as used by
42 @implementation NGImap4ConnectionManager(SOGoMailManager)
44 + (id)defaultMailManager {
45 return [self defaultConnectionManager];
49 - (NSException *)errorForMissingEntryAtURL:(NSURL *)_url {
51 return [NSException exceptionWithHTTPStatus:404 /* Not Found */
52 reason:@"Did not find mail URL"];
58 /* folder hierarchy */
60 - (NSArray *)subfoldersForURL:(NSURL *)_url password:(NSString *)_pwd {
61 NGImap4Connection *entry;
63 /* check connection cache */
64 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
67 return [entry subfoldersForURL:_url];
70 - (NSArray *)allFoldersForURL:(NSURL *)_url password:(NSString *)_pwd {
71 NGImap4Connection *entry;
73 /* check connection cache */
74 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
77 return [entry allFoldersForURL:_url];
82 - (NSArray *)fetchUIDsInURL:(NSURL *)_url qualifier:(id)_qualifier
83 sortOrdering:(id)_so password:(NSString *)_pwd
86 sortOrdering can be an NSString, an EOSortOrdering or an array of EOS.
88 NGImap4Connection *entry;
90 /* check connection cache */
91 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
94 return [entry fetchUIDsInURL:_url qualifier:_qualifier sortOrdering:_so];
97 - (NSArray *)fetchUIDs:(NSArray *)_uids inURL:(NSURL *)_url
98 parts:(NSArray *)_parts password:(NSString *)_pwd
100 // currently returns a dict?!
104 BODY.PEEK[<section>]<<partial>>
105 BODY [this is the bodystructure, supported]
106 BODYSTRUCTURE [not supported yet!]
107 ENVELOPE [this is a parsed header, but does not include type]
115 NGImap4Connection *entry;
119 if ([_uids count] == 0)
120 return nil; // TODO: might break empty folders?! return a dict!
122 /* check connection cache */
123 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
126 return [entry fetchUIDs:_uids inURL:_url parts:_parts];
129 - (NSException *)expungeAtURL:(NSURL *)_url password:(NSString *)_pwd {
130 NGImap4Connection *entry;
132 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
133 return [self errorForMissingEntryAtURL:_url];
135 return [entry expungeAtURL:_url];
138 - (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts password:(NSString *)_pwd{
139 NGImap4Connection *entry;
141 if (![_url isNotNull]) return nil;
142 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
143 return [self errorForMissingEntryAtURL:_url];
145 return [entry fetchURL:_url parts:_parts];
148 - (NSData *)fetchContentOfBodyPart:(NSString *)_partId
149 atURL:(NSURL *)_url password:(NSString *)_pwd
151 NGImap4Connection *entry;
153 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
154 return nil; // TODO: improve?
156 return [entry fetchContentOfBodyPart:_partId atURL:_url];
159 - (NSException *)addOrRemove:(BOOL)_flag flags:(id)_f
160 toURL:(NSURL *)_url password:(NSString *)_p
162 NGImap4Connection *entry;
164 if ((entry = [self connectionForURL:_url password:_p]) == nil)
165 return [self errorForMissingEntryAtURL:_url];
167 return [entry addOrRemove:_flag flags:_f toURL:_url];
169 - (NSException *)addFlags:(id)_f toURL:(NSURL *)_u password:(NSString *)_p {
170 return [self addOrRemove:YES flags:_f toURL:_u password:_p];
172 - (NSException *)removeFlags:(id)_f toURL:(NSURL *)_u password:(NSString *)_p {
173 return [self addOrRemove:NO flags:_f toURL:_u password:_p];
176 - (NSException *)markURLDeleted:(NSURL *)_url password:(NSString *)_p {
177 return [self addOrRemove:YES flags:@"Deleted" toURL:_url password:_p];
180 - (NSException *)postData:(NSData *)_data flags:(id)_f
181 toFolderURL:(NSURL *)_url password:(NSString *)_p
183 NGImap4Connection *entry;
185 if (![_url isNotNull]) return nil;
187 if ((entry = [self connectionForURL:_url password:_p]) == nil)
188 return [self errorForMissingEntryAtURL:_url];
190 return [entry postData:_data flags:_f toFolderURL:_url];
193 - (NSException *)copyMailURL:(NSURL *)_srcurl toFolderURL:(NSURL *)_desturl
194 password:(NSString *)_pwd
196 NGImap4Connection *entry;
198 /* check connection cache */
200 if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil)
201 return [self errorForMissingEntryAtURL:_srcurl];
203 /* check whether URLs are on different servers */
205 if ([self connectionForURL:_desturl password:_pwd] != entry) {
206 // TODO: find a better error code
207 return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */
208 reason:@"source and destination on different servers"];
211 return [entry copyMailURL:_srcurl toFolderURL:_desturl];
214 /* managing folders */
216 - (BOOL)isPermissionDeniedResult:(id)_result {
217 if ([[_result valueForKey:@"result"] intValue] != 0)
220 return [[_result valueForKey:@"reason"]
221 isEqualToString:@"Permission denied"];
224 - (BOOL)doesMailboxExistAtURL:(NSURL *)_url password:(NSString *)_pwd {
225 NGImap4Connection *entry;
227 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
230 return [entry doesMailboxExistAtURL:_url];
233 - (id)infoForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
234 NGImap4Connection *entry;
236 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
237 return [self errorForMissingEntryAtURL:_url];
239 return [entry infoForMailboxAtURL:_url];
242 - (NSException *)createMailbox:(NSString *)_mailbox atURL:(NSURL *)_url
243 password:(NSString *)_pwd
245 NGImap4Connection *entry;
247 /* check connection cache */
248 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
249 return [self errorForMissingEntryAtURL:_url];
251 return [entry createMailbox:_mailbox atURL:_url];
254 - (NSException *)deleteMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
255 NGImap4Connection *entry;
257 /* check connection cache */
259 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
260 return [self errorForMissingEntryAtURL:_url];
262 return [entry deleteMailboxAtURL:_url];
265 - (NSException *)moveMailboxAtURL:(NSURL *)_srcurl toURL:(NSURL *)_desturl
266 password:(NSString *)_pwd
268 NGImap4Connection *entry;
270 /* check connection cache */
272 if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil)
273 return [self errorForMissingEntryAtURL:_srcurl];
275 /* check whether URLs are on different servers */
277 if ([self connectionForURL:_desturl password:_pwd] != entry) {
278 // TODO: find a better error code
279 return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */
280 reason:@"source and destination on different servers"];
283 return [entry moveMailboxAtURL:_srcurl toURL:_desturl];
286 - (NSDictionary *)aclForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
288 Returns a mapping of uid => permission strings, eg:
292 NGImap4Connection *entry;
294 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
295 return (id)[self errorForMissingEntryAtURL:_url];
297 return [entry aclForMailboxAtURL:_url];
300 - (NSString *)myRightsForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
301 NGImap4Connection *entry;
303 if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
304 return (id)[self errorForMissingEntryAtURL:_url];
306 return [entry myRightsForMailboxAtURL:_url];
309 /* bulk flag adding (eg used for empty/trash) */
311 - (NSException *)addFlags:(id)_f toAllMessagesInURL:(NSURL *)_url
312 password:(NSString *)_p
314 NGImap4Connection *entry;
316 if (![_url isNotNull]) return nil;
317 if (![_f isNotNull]) return nil;
319 if ((entry = [self connectionForURL:_url password:_p]) == nil)
320 return [self errorForMissingEntryAtURL:_url];
322 return [entry addFlags:_f toAllMessagesInURL:_url];
325 @end /* NGImap4ConnectionManager(SOGoMailManager) */