]> err.no Git - scalable-opengroupware.org/blob - SOGo/SoObjects/Mailer/SOGoMailFolder.m
improved special mail folders
[scalable-opengroupware.org] / SOGo / SoObjects / Mailer / SOGoMailFolder.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 "SOGoMailFolder.h"
23 #include "SOGoMailObject.h"
24 #include "SOGoMailAccount.h"
25 #include "SOGoMailManager.h"
26 #include "common.h"
27
28 @implementation SOGoMailFolder
29
30 - (void)dealloc {
31   [self->filenames  release];
32   [self->folderType release];
33   [super dealloc];
34 }
35
36 /* IMAP4 */
37
38 - (NSString *)relativeImap4Name {
39   return [self nameInContainer];
40 }
41
42 /* listing the available folders */
43
44 - (NSArray *)toManyRelationshipKeys {
45   return [[self mailManager] subfoldersForURL:[self imap4URL] 
46                              password:[self imap4Password]];
47 }
48 - (NSArray *)toOneRelationshipKeys {
49   NSArray  *uids;
50   unsigned count;
51   
52   if (self->filenames != nil)
53     return [self->filenames isNotNull] ? self->filenames : nil;
54   
55   uids = [self fetchUIDsMatchingQualifier:nil sortOrdering:@"DATE"];
56   if ([uids isKindOfClass:[NSException class]])
57     return nil;
58   
59   if ((count = [uids count]) == 0) {
60     self->filenames = [[NSArray alloc] init];
61   }
62   else {
63     NSMutableArray *keys;
64     unsigned i;
65     
66     keys = [[NSMutableArray alloc] initWithCapacity:count];
67     for (i = 0; i < count; i++) {
68       NSString *k;
69       
70       k = [[uids objectAtIndex:i] stringValue];
71       k = [k stringByAppendingString:@".mail"];
72       [keys addObject:k];
73     }
74     self->filenames = [keys copy];
75     [keys release];
76   }
77   return self->filenames;
78 }
79
80 /* messages */
81
82 - (NSArray *)fetchUIDsMatchingQualifier:(id)_q sortOrdering:(id)_so {
83   /* seems to return an NSArray of NSNumber's */
84   return [[self mailManager] fetchUIDsInURL:[self imap4URL]
85                              qualifier:_q sortOrdering:_so
86                              password:[self imap4Password]];
87 }
88
89 - (NSArray *)fetchUIDs:(NSArray *)_uids parts:(NSArray *)_parts {
90   return [[self mailManager] fetchUIDs:_uids inURL:[self imap4URL]
91                              parts:_parts
92                              password:[self imap4Password]];
93 }
94
95 - (NSException *)postData:(NSData *)_data flags:(id)_flags {
96   return [[self mailManager] postData:_data flags:_flags
97                              toFolderURL:[self imap4URL]
98                              password:[self imap4Password]];
99 }
100
101 - (NSException *)expunge {
102   return [[self mailManager] expungeAtURL:[self imap4URL]
103                              password:[self imap4Password]];
104 }
105
106 /* name lookup */
107
108 - (BOOL)isMessageKey:(NSString *)_key inContext:(id)_ctx {
109   /*
110     Every key starting with a digit is consider an IMAP4 message key. This is
111     not entirely correct since folders could also start with a number.
112     
113     If we want to support folders beginning with numbers, we would need to
114     scan the folder list for the _key, which would make everything quite a bit
115     slower.
116     TODO: support this mode using a default.
117   */
118   if ([_key length] == 0)
119     return NO;
120   
121   if (isdigit([_key characterAtIndex:0]))
122     return YES;
123   
124   return NO;
125 }
126
127 - (id)lookupImap4Folder:(NSString *)_key inContext:(id)_ctx {
128   // TODO: we might want to check for existence prior controller creation
129   return [[[SOGoMailFolder alloc] initWithName:_key 
130                                   inContainer:self] autorelease];
131 }
132 - (id)lookupImap4Message:(NSString *)_key inContext:(id)_ctx {
133   // TODO: we might want to check for existence prior controller creation
134   return [[[SOGoMailObject alloc] initWithName:_key 
135                                   inContainer:self] autorelease];
136 }
137
138 - (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
139   id obj;
140   
141   /* first check attributes directly bound to the application */
142   if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]) != nil)
143     return obj;
144   
145   obj = [self isMessageKey:_key inContext:_ctx]
146     ? [self lookupImap4Message:_key inContext:_ctx]
147     : [self lookupImap4Folder:_key  inContext:_ctx];
148   if (obj != nil)
149     return obj;
150   
151   /* return 404 to stop acquisition */
152   return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
153 }
154
155 /* WebDAV */
156
157 - (BOOL)davIsCollection {
158   return YES;
159 }
160
161 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
162   return [[self mailManager] createMailbox:_name atURL:[self imap4URL]
163                              password:[self imap4Password]];
164 }
165
166 /* folder type */
167
168 - (NSString *)outlookFolderClass {
169   // TODO: detect Trash/Sent/Drafts folders
170   SOGoMailAccount *account;
171   NSString *n;
172
173   if (self->folderType != nil)
174     return self->folderType;
175   
176   account = [self mailAccountFolder];
177   n       = [self nameInContainer];
178   
179   if ([n isEqualToString:[account trashFolderNameInContext:nil]])
180     self->folderType = @"IPF.Trash";
181   else if ([n isEqualToString:[account inboxFolderNameInContext:nil]])
182     self->folderType = @"IPF.Inbox";
183   else if ([n isEqualToString:[account sentFolderNameInContext:nil]])
184     self->folderType = @"IPF.Sent";
185   else
186     self->folderType = @"IPF.Folder";
187   
188   return self->folderType;
189 }
190
191 /* operations */
192
193 - (NSException *)delete {
194   /* Note: overrides SOGoObject -delete */
195   return [[self mailManager] deleteMailboxAtURL:[self imap4URL]
196                              password:[self imap4Password]];
197 }
198
199 @end /* SOGoMailFolder */