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 #include <NGObjWeb/SoApplication.h>
24 @interface SOGo : SoApplication
26 NSMutableDictionary *localeLUT;
29 - (NSDictionary *) currentLocaleConsideringLanguages:(NSArray *)_langs;
30 - (NSDictionary *) localeForLanguageNamed:(NSString *)_name;
34 #include "SOGoProductLoader.h"
35 #include <WEExtensions/WEResourceManager.h>
36 #include <SOGo/SOGoAuthenticator.h>
37 #include <SOGo/SOGoUserFolder.h>
38 #include <SOGo/SOGoPermissions.h>
43 static unsigned int vMemSizeLimit = 0;
44 static BOOL doCrashOnSessionCreate = NO;
46 #ifdef GNUSTEP_BASE_LIBRARY
47 static BOOL debugObjectAllocation = NO;
52 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
53 SoClassSecurityInfo *sInfo;
57 doCrashOnSessionCreate = [ud boolForKey:@"SOGoCrashOnSessionCreate"];
58 #ifdef GNUSTEP_BASE_LIBRARY
59 debugObjectAllocation = [ud boolForKey: @"SOGoDebugObjectAllocation"];
60 if (debugObjectAllocation)
62 NSLog (@"activating stats on object allocation");
63 GSDebugAllocationActive (YES);
67 /* vMem size check - default is 200MB */
69 tmp = [ud objectForKey: @"SxVMemLimit"];
70 vMemSizeLimit = ((tmp != nil) ? [tmp intValue] : 200);
71 if (vMemSizeLimit > 0)
72 NSLog(@"Note: vmem size check enabled: shutting down app when "
73 @"vmem > %d MB", vMemSizeLimit);
74 #if LIB_FOUNDATION_LIBRARY
75 if ([ud boolForKey:@"SOGoEnableDoubleReleaseCheck"])
76 [NSAutoreleasePool enableDoubleReleaseCheck: YES];
79 /* SoClass security declarations */
80 sInfo = [self soClassSecurityInfo];
81 /* require View permission to access the root (bound to authenticated ...) */
82 [sInfo declareObjectProtected: SoPerm_View];
84 /* to allow public access to all contained objects (subkeys) */
85 [sInfo setDefaultAccess: @"allow"];
87 basicRoles = [NSArray arrayWithObjects: SoRole_Authenticated,
88 SOGoRole_FreeBusy, nil];
90 /* require Authenticated role for View and WebDAV */
91 [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_View];
92 [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess];
97 if ((self = [super init]))
99 WOResourceManager *rm;
101 /* ensure core SoClass'es are setup */
102 [$(@"SOGoObject") soClass];
103 [$(@"SOGoContentObject") soClass];
104 [$(@"SOGoFolder") soClass];
106 /* setup locale cache */
107 localeLUT = [[NSMutableDictionary alloc] initWithCapacity:2];
110 [[SOGoProductLoader productLoader] loadProducts];
112 /* setup resource manager */
113 rm = [[WEResourceManager alloc] init];
114 [self setResourceManager:rm];
128 - (id) authenticatorInContext: (id) _ctx
130 return [$(@"SOGoAuthenticator") sharedSOGoAuthenticator];
135 - (BOOL) isUserName: (NSString *) _key
138 if ([_key length] < 1)
141 if (isdigit([_key characterAtIndex:0]))
147 - (id)lookupUser:(NSString *)_key inContext:(id)_ctx {
148 return [[[$(@"SOGoUserFolder") alloc]
149 initWithName:_key inContainer:self] autorelease];
152 - (void) _setupLocaleInContext: (WOContext *) _ctx
155 NSDictionary *locale;
157 if ([[_ctx valueForKey:@"locale"] isNotNull])
160 langs = [[_ctx request] browserLanguages];
161 locale = [self currentLocaleConsideringLanguages:langs];
162 [_ctx takeValue:locale forKey:@"locale"];
165 - (id) lookupName: (NSString *) _key
167 acquire: (BOOL) _flag
171 #ifdef GNUSTEP_BASE_LIBRARY
172 if (debugObjectAllocation)
173 NSLog(@"objects allocated\n%s", GSDebugAllocationList (YES));
175 /* put locale info into the context in case it's not there */
176 [self _setupLocaleInContext:_ctx];
178 /* first check attributes directly bound to the application */
179 if ((obj = [super lookupName:_key inContext:_ctx acquire:_flag]))
183 The problem is, that at this point we still get request for resources,
186 Addition: we also get queries for various other methods, like "GET" if
187 no method was provided in the query path.
190 if ([_key isEqualToString:@"favicon.ico"])
193 if ([self isUserName:_key inContext:_ctx])
194 return [self lookupUser:_key inContext:_ctx];
201 - (NSString *) davDisplayName
203 /* this is used in the UI, eg in the navigation */
207 /* exception handling */
209 - (WOResponse *) handleException: (NSException *) _exc
210 inContext: (WOContext *) _ctx
212 printf("EXCEPTION: %s\n", [[_exc description] cString]);
216 /* runtime maintenance */
218 - (void) checkIfDaemonHasToBeShutdown
222 if (vMemSizeLimit > 0)
224 vmem = [[NSProcessInfo processInfo] virtualMemorySize]/1048576;
226 if (vmem > vMemSizeLimit)
229 @"terminating app, vMem size limit (%d MB) has been reached"
230 @" (currently %d MB)",
231 vMemSizeLimit, vmem];
232 // if (debugObjectAllocation)
233 // [self _dumpClassAllocation];
239 - (WOResponse *) dispatchRequest: (WORequest *) _request
241 static NSArray *runLoopModes = nil;
244 resp = [super dispatchRequest: _request];
246 if (![self isTerminating])
249 runLoopModes = [[NSArray alloc] initWithObjects: NSDefaultRunLoopMode, nil];
251 // TODO: a bit complicated? (-perform:afterDelay: doesn't work?)
252 [[NSRunLoop currentRunLoop] performSelector:
253 @selector (checkIfDaemonHasToBeShutdown)
254 target: self argument: nil
255 order:1 modes:runLoopModes];
261 /* session management */
263 - (id) createSessionForRequest: (WORequest *) _request
265 [self warnWithFormat: @"session creation requested!"];
266 if (doCrashOnSessionCreate)
268 return [super createSessionForRequest:_request];
273 - (NSDictionary *) currentLocaleConsideringLanguages: (NSArray *) langs
275 NSEnumerator *enumerator;
277 NSDictionary *locale;
279 enumerator = [langs objectEnumerator];
282 lname = [enumerator nextObject];
283 while (lname && !locale)
285 locale = [self localeForLanguageNamed: lname];
286 lname = [enumerator nextObject];
290 locale = [self localeForLanguageNamed: @"English"];
292 /* no appropriate language, fallback to default */
296 - (NSString *) pathToLocaleForLanguageNamed: (NSString *) _name
298 static Class MainProduct = Nil;
301 lpath = [[self resourceManager] pathForResourceNamed: @"Locale"
303 languages: [NSArray arrayWithObject:_name]];
308 MainProduct = $(@"MainUIProduct");
310 [self errorWithFormat: @"did not find MainUIProduct class!"];
313 lpath = [(id) MainProduct pathToLocaleForLanguageNamed: _name];
321 - (NSDictionary *) localeForLanguageNamed: (NSString *) _name
325 NSDictionary *locale;
328 if ([_name length] > 0)
330 locale = [localeLUT objectForKey: _name];
333 lpath = [self pathToLocaleForLanguageNamed:_name];
336 data = [NSData dataWithContentsOfFile: lpath];
339 data = [[[NSString alloc] initWithData: data
340 encoding: NSUTF8StringEncoding] autorelease];
341 locale = [data propertyList];
343 [localeLUT setObject: locale forKey: _name];
345 [self logWithFormat:@"%s couldn't load locale with name:%@",
350 [self logWithFormat:@"%s didn't find locale with name: %@",
355 [self errorWithFormat:@"did not find Locale for language: %@", _name];
359 [self errorWithFormat:@"%s: name parameter must not be nil!",
360 __PRETTY_FUNCTION__];
365 /* name (used by the WEResourceManager) */