]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Mailer/SOGoMailManager.m
moved SOGo files up
[scalable-opengroupware.org] / SoObjects / Mailer / SOGoMailManager.m
1 /*
2   Copyright (C) 2004-2005 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include "SOGoMailManager.h"
23 #include <NGImap4/NGImap4Connection.h>
24 #include <NGImap4/NGImap4ConnectionManager.h>
25 #include "common.h"
26
27 /*
28   Could check read-write state:
29     dict = [[self->context client] select:[self absoluteName]];
30     self->isReadOnly = 
31       [[dict objectForKey:@"access"] isEqualToString:@"READ-WRITE"]
32       ? NoNumber : YesNumber;
33   
34   TODO: to implement copy, use "uid copy" instead of "copy" as used by
35         NGImap4Client.
36 */
37
38 @implementation NGImap4ConnectionManager(SOGoMailManager)
39
40 + (id)defaultMailManager {
41   return [self defaultConnectionManager];
42 }
43
44
45 - (NSException *)errorForMissingEntryAtURL:(NSURL *)_url {
46   // TODO: improve
47   return [NSException exceptionWithHTTPStatus:404 /* Not Found */
48                       reason:@"Did not find mail URL"];
49 }
50
51 /* client object */
52
53
54 /* folder hierarchy */
55
56 - (NSArray *)subfoldersForURL:(NSURL *)_url password:(NSString *)_pwd {
57   NGImap4Connection *entry;
58
59   /* check connection cache */
60   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
61     return nil;
62   
63   return [entry subfoldersForURL:_url];
64 }
65
66 - (NSArray *)allFoldersForURL:(NSURL *)_url password:(NSString *)_pwd {
67   NGImap4Connection *entry;
68   
69   /* check connection cache */
70   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
71     return nil;
72   
73   return [entry allFoldersForURL:_url];
74 }
75
76 /* messages */
77
78 - (NSArray *)fetchUIDsInURL:(NSURL *)_url qualifier:(id)_qualifier
79   sortOrdering:(id)_so password:(NSString *)_pwd
80 {
81   /* 
82      sortOrdering can be an NSString, an EOSortOrdering or an array of EOS.
83   */
84   NGImap4Connection *entry;
85   
86   /* check connection cache */
87   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
88     return nil;
89   
90   return [entry fetchUIDsInURL:_url qualifier:_qualifier sortOrdering:_so];
91 }
92
93 - (NSArray *)fetchUIDs:(NSArray *)_uids inURL:(NSURL *)_url
94   parts:(NSArray *)_parts password:(NSString *)_pwd
95 {
96   // currently returns a dict?!
97   /*
98     Allowed fetch keys:
99       UID
100       BODY.PEEK[<section>]<<partial>>
101       BODY            [this is the bodystructure, supported]
102       BODYSTRUCTURE   [not supported yet!]
103       ENVELOPE        [this is a parsed header, but does not include type]
104       FLAGS
105       INTERNALDATE
106       RFC822
107       RFC822.HEADER
108       RFC822.SIZE
109       RFC822.TEXT
110   */
111   NGImap4Connection *entry;
112   
113   if (_uids == nil)
114     return nil;
115   if ([_uids count] == 0)
116     return nil; // TODO: might break empty folders?! return a dict!
117   
118   /* check connection cache */
119   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
120     return nil;
121   
122   return [entry fetchUIDs:_uids inURL:_url parts:_parts];
123 }
124
125 - (NSException *)expungeAtURL:(NSURL *)_url password:(NSString *)_pwd {
126   NGImap4Connection *entry;
127   
128   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
129     return [self errorForMissingEntryAtURL:_url];
130   
131   return [entry expungeAtURL:_url];
132 }
133
134 - (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts password:(NSString *)_pwd{
135   NGImap4Connection *entry;
136   
137   if (![_url isNotNull]) return nil;
138   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
139     return [self errorForMissingEntryAtURL:_url];
140   
141   return [entry fetchURL:_url parts:_parts];
142 }
143
144 - (NSData *)fetchContentOfBodyPart:(NSString *)_partId
145   atURL:(NSURL *)_url password:(NSString *)_pwd
146 {
147   NGImap4Connection *entry;
148
149   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
150     return nil; // TODO: improve?
151
152   return [entry fetchContentOfBodyPart:_partId atURL:_url];
153 }
154
155 - (NSException *)addOrRemove:(BOOL)_flag flags:(id)_f
156   toURL:(NSURL *)_url password:(NSString *)_p
157 {
158   NGImap4Connection *entry;
159
160   if ((entry = [self connectionForURL:_url password:_p]) == nil)
161     return [self errorForMissingEntryAtURL:_url];
162
163   return [entry addOrRemove:_flag flags:_f toURL:_url];
164 }
165 - (NSException *)addFlags:(id)_f toURL:(NSURL *)_u password:(NSString *)_p {
166   return [self addOrRemove:YES flags:_f toURL:_u password:_p];
167 }
168 - (NSException *)removeFlags:(id)_f toURL:(NSURL *)_u password:(NSString *)_p {
169   return [self addOrRemove:NO flags:_f toURL:_u password:_p];
170 }
171
172 - (NSException *)markURLDeleted:(NSURL *)_url password:(NSString *)_p {
173   return [self addOrRemove:YES flags:@"Deleted" toURL:_url password:_p];
174 }
175
176 - (NSException *)postData:(NSData *)_data flags:(id)_f
177   toFolderURL:(NSURL *)_url password:(NSString *)_p
178 {
179   NGImap4Connection *entry;
180
181   if (![_url isNotNull]) return nil;
182   
183   if ((entry = [self connectionForURL:_url password:_p]) == nil)
184     return [self errorForMissingEntryAtURL:_url];
185   
186   return [entry postData:_data flags:_f toFolderURL:_url];
187 }
188
189 - (NSException *)copyMailURL:(NSURL *)_srcurl toFolderURL:(NSURL *)_desturl
190   password:(NSString *)_pwd
191 {
192   NGImap4Connection *entry;
193   
194   /* check connection cache */
195   
196   if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil)
197     return [self errorForMissingEntryAtURL:_srcurl];
198   
199   /* check whether URLs are on different servers */
200   
201   if ([self connectionForURL:_desturl password:_pwd] != entry) {
202     // TODO: find a better error code
203     return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */
204                         reason:@"source and destination on different servers"];
205   }  
206   
207   return [entry copyMailURL:_srcurl toFolderURL:_desturl];
208 }
209
210 /* managing folders */
211
212 - (BOOL)isPermissionDeniedResult:(id)_result {
213   if ([[_result valueForKey:@"result"] intValue] != 0)
214     return NO;
215   
216   return [[_result valueForKey:@"reason"] 
217                    isEqualToString:@"Permission denied"];
218 }
219
220 - (BOOL)doesMailboxExistAtURL:(NSURL *)_url password:(NSString *)_pwd {
221   NGImap4Connection *entry;
222   
223   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
224     return NO;
225   
226   return [entry doesMailboxExistAtURL:_url];
227 }
228
229 - (id)infoForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
230   NGImap4Connection *entry;
231   
232   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
233     return [self errorForMissingEntryAtURL:_url];
234   
235   return [entry infoForMailboxAtURL:_url];
236 }
237
238 - (NSException *)createMailbox:(NSString *)_mailbox atURL:(NSURL *)_url
239   password:(NSString *)_pwd
240 {
241   NGImap4Connection *entry;
242   
243   /* check connection cache */
244   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
245     return [self errorForMissingEntryAtURL:_url];
246
247   return [entry createMailbox:_mailbox atURL:_url];
248 }
249
250 - (NSException *)deleteMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
251   NGImap4Connection *entry;
252   
253   /* check connection cache */
254   
255   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
256     return [self errorForMissingEntryAtURL:_url];
257   
258   return [entry deleteMailboxAtURL:_url];
259 }
260
261 - (NSException *)moveMailboxAtURL:(NSURL *)_srcurl toURL:(NSURL *)_desturl
262   password:(NSString *)_pwd
263 {
264   NGImap4Connection *entry;
265   
266   /* check connection cache */
267   
268   if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil)
269     return [self errorForMissingEntryAtURL:_srcurl];
270   
271   /* check whether URLs are on different servers */
272   
273   if ([self connectionForURL:_desturl password:_pwd] != entry) {
274     // TODO: find a better error code
275     return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */
276                         reason:@"source and destination on different servers"];
277   }  
278   
279   return [entry moveMailboxAtURL:_srcurl toURL:_desturl];
280 }
281
282 - (NSDictionary *)aclForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
283   /*
284     Returns a mapping of uid => permission strings, eg:
285       guizmo.g = lrs;
286       root     = lrswipcda;
287   */
288   NGImap4Connection *entry;
289   
290   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
291     return (id)[self errorForMissingEntryAtURL:_url];
292   
293   return [entry aclForMailboxAtURL:_url];
294 }
295
296 - (NSString *)myRightsForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd {
297   NGImap4Connection *entry;
298   
299   if ((entry = [self connectionForURL:_url password:_pwd]) == nil)
300     return (id)[self errorForMissingEntryAtURL:_url];
301
302   return [entry myRightsForMailboxAtURL:_url];
303 }
304
305 /* bulk flag adding (eg used for empty/trash) */
306
307 - (NSException *)addFlags:(id)_f toAllMessagesInURL:(NSURL *)_url
308   password:(NSString *)_p
309 {
310   NGImap4Connection *entry;
311   
312   if (![_url isNotNull]) return nil;
313   if (![_f   isNotNull]) return nil;
314   
315   if ((entry = [self connectionForURL:_url password:_p]) == nil)
316     return [self errorForMissingEntryAtURL:_url];
317   
318   return [entry addFlags:_f toAllMessagesInURL:_url];
319 }
320
321 @end /* NGImap4ConnectionManager(SOGoMailManager) */