]> err.no Git - scalable-opengroupware.org/blob - SoObjects/SOGo/SOGoGroupFolder.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1117 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / SOGo / SOGoGroupFolder.m
1 /*
2   Copyright (C) 2004 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 #import <Foundation/NSArray.h>
23 #import <Foundation/NSString.h>
24
25 #import <NGObjWeb/WOContext.h>
26 #import <NGObjWeb/WOContext+SoObjects.h>
27
28 #import <NGObjWeb/NSException+HTTP.h>
29 #import <NGExtensions/NGLogger.h>
30 #import <NGExtensions/NGLoggerManager.h>
31 #import <NGExtensions/NSObject+Logs.h>
32 #import <NGExtensions/NSNull+misc.h>
33
34 #import "SOGoGroupFolder.h"
35
36 @implementation SOGoGroupFolder
37
38 static NGLogger *logger = nil;
39
40 + (void) initialize
41 {
42   NGLoggerManager *lm;
43
44   if (!logger)
45     {
46       lm = [NGLoggerManager defaultLoggerManager];
47       logger = [lm loggerForDefaultKey:@"SOGoGroupFolderDebugEnabled"];
48     }
49 }
50
51 - (void) dealloc
52 {
53   [uidToFolder release];
54   [folders     release];
55   [super dealloc];
56 }
57
58 /* logging */
59
60 - (id)debugLogger {
61   return logger;
62 }
63
64 /* accessors */
65
66 - (NSArray *)uids {
67   [self errorWithFormat:@"instantiated abstract Group folder class!"];
68   return nil;
69 }
70
71 /* folder management */
72
73 - (id)_primaryLookupFolderForUID:(NSString *)_uid inContext:(id)_ctx {
74   NSException *error = nil;
75   NSArray     *path;
76   id          ctx, result;
77
78   /* create subcontext, so that we don't destroy our environment */
79   
80   if ((ctx = [_ctx createSubContext]) == nil) {
81     [self errorWithFormat:@"could not create SOPE subcontext!"];
82     return nil;
83   }
84   
85   /* build path */
86   
87   path = _uid != nil ? [NSArray arrayWithObjects:&_uid count:1] : nil;
88   
89   /* traverse path */
90   
91   result = [[ctx application] traversePathArray:path inContext:ctx
92                               error:&error acquire:NO];
93   if (error != nil) {
94     [self errorWithFormat:@"folder lookup failed (uid=%@): %@",
95             _uid, error];
96     return nil;
97   }
98   
99   if (logger)
100     [self debugWithFormat:@"Note: got folder for uid %@ path %@: %@",
101                                 _uid, [path componentsJoinedByString:@"=>"], result];
102   return result;
103 }
104
105 - (void)_setupFolders {
106   NSMutableDictionary *md;
107   NSMutableArray      *ma;
108   NSArray  *luids;
109   unsigned i, count;
110   
111   if (uidToFolder != nil)
112     return;
113   if ((luids = [self uids]) == nil)
114     return;
115   
116   count = [luids count];
117   ma = [NSMutableArray arrayWithCapacity:count + 1];
118   md = [NSMutableDictionary dictionaryWithCapacity:count];
119   
120   for (i = 0; i < count; i++) {
121     NSString *uid;
122     id folder;
123     
124     uid    = [luids objectAtIndex:i];
125     folder = [self _primaryLookupFolderForUID:uid inContext: context];
126     
127     if ([folder isNotNull]) {
128       [md setObject:folder forKey:uid];
129       [ma addObject:folder];
130     }
131     else
132       [ma addObject:[NSNull null]];
133   }
134   
135   /* fix results */
136   uidToFolder = [md copy];
137   folders     = [[NSArray alloc] initWithArray:ma];
138 }
139
140 - (NSArray *)memberFolders {
141   [self _setupFolders];
142   return folders;
143 }
144
145 - (id)folderForUID:(NSString *)_uid {
146   [self _setupFolders];
147   
148   if ([_uid length] == 0)
149     return nil;
150   
151   return [uidToFolder objectForKey:_uid];
152 }
153
154 - (void) resetFolderCaches
155 {
156   [uidToFolder release];
157   uidToFolder = nil;
158   [folders release];
159   folders     = nil;
160 }
161
162 - (void) sleep
163 {
164   [self resetFolderCaches];
165   [super sleep];
166 }
167
168 /* SOPE */
169
170 - (BOOL) isFolderish
171 {
172   return YES;
173 }
174
175 /* looking up shared objects */
176
177 - (SOGoGroupsFolder *) lookupGroupsFolder
178 {
179   return [[self container] lookupGroupsFolder];
180 }
181
182 /* pathes */
183
184 /* name lookup */
185
186 - (id) groupCalendar: (NSString *) _key
187            inContext: (id) _ctx
188 {
189   static Class calClass = Nil;
190   id calendar;
191   
192   if (calClass == Nil)
193     calClass = NSClassFromString(@"SOGoGroupAppointmentFolder");
194   if (calClass == Nil) {
195     [self errorWithFormat:@"missing SOGoGroupAppointmentFolder class!"];
196     return nil;
197   }
198   
199   calendar = [[calClass alloc] initWithName:_key inContainer:self];
200   
201   // TODO: should we pass over the uids in questions or should the
202   //       appointment folder query its container for that info?
203   
204   return [calendar autorelease];
205 }
206
207 - (id) lookupName: (NSString *) _key
208         inContext: (id) _ctx
209           acquire: (BOOL) _flag
210 {
211   id obj;
212   
213   /* first check attributes directly bound to the application */
214   if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
215     return obj;
216   
217   if ([_key isEqualToString:@"Calendar"])
218     return [self groupCalendar:_key inContext:_ctx];
219   
220   /* return 404 to stop acquisition */
221   return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
222 }
223
224 @end /* SOGoGroupFolder */