/*
- Copyright (C) 2000-2004 SKYRIX Software AG
+ Copyright (C) 2000-2005 SKYRIX Software AG
+ Copyright (C) 2006 Helge Hess
- This file is part of OpenGroupware.org.
+ This file is part of SOPE.
- OGo is free software; you can redistribute it and/or modify it under
+ SOPE is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING. If not, write to the
+ License along with SOPE; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#include <NGObjWeb/WOStatisticsStore.h>
#include <NGObjWeb/WODynamicElement.h>
#include <NGObjWeb/WOTemplate.h>
-#import <EOControl/EOControl.h>
+#include <EOControl/EOControl.h>
#include "common.h"
#include <time.h>
+#if GNU_RUNTIME
+# include <objc/sarray.h>
+#endif
+
@interface WOApplication(PrivateMethods)
+ (id)logger;
- (id)_loadComponentDefinitionWithName:(NSString *)_name
@implementation WOApplication
+#if 1 // TODO: why is that? why isn't that set by a default?
+static NSString *defaultCompRqHandlerClassName = @"OWViewRequestHandler";
+#else
+static NSString *defaultCompRqHandlerClassName = @"WOComponentRequestHandler";
+#endif
+
+ (int)version {
return [super version] + 5 /* v6 */;
}
debugOn = [WOApplication isDebuggingEnabled];
if (!debugOn)
[[self logger] setLogLevel:NGLogLevelInfo];
+ else
+ NSLog(@"Note: WOApplication debugging is enabled.");
if (classLock == nil) classLock = [[NSRecursiveLock alloc] init];
ud = [NSUserDefaults standardUserDefaults];
pi = [NSProcessInfo processInfo];
env = [pi environment];
- if ([env objectForKey:@"GNUSTEP_SYSTEM_ROOT"] != nil) {
+ if ([[env objectForKey:@"GNUSTEP_SYSTEM_ROOT"] isNotNull]) {
isFlattened = [[[env objectForKey:@"GNUSTEP_FLATTENED"]
lowercaseString] isEqualToString:@"yes"];
}
- (id)initWithName:(NSString *)_name {
[WOApplication _initializeWOApp];
- if ((self = [super init])) {
+ if ((self = [super init]) != nil) {
NSUserDefaults *ud;
WORequestHandler *rh;
NSString *rk;
self->requestHandlerRegistry =
NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 8);
- rk = [WOApplication componentRequestHandlerKey];
-#if 1
- rh = [[NSClassFromString(@"OWViewRequestHandler") alloc] init];
-#else
- rh = [[NSClassFromString(@"WOComponentRequestHandler") alloc] init];
-#endif
- if ([rk length] > 0 && (rh != nil))
+ if ((rk = [WOApplication componentRequestHandlerKey]) == nil) {
+ [self logWithFormat:
+ @"WARNING: no component request handler key is specified, "
+ @"this probably means that share/ngobjweb/Defaults.plist "
+ @"could not get loaded (permissions?)"];
+ }
+ rh = [[NSClassFromString(defaultCompRqHandlerClassName) alloc] init];
+ if ([rk isNotEmpty] && [rh isNotNull])
[self registerRequestHandler:rh forKey:rk];
[rh release]; rh = nil;
rk = [WOApplication directActionRequestHandlerKey];
rh = [[NSClassFromString(@"WODirectActionRequestHandler") alloc] init];
- if ([rk length] > 0 && rh != nil)
+ if ([rk isNotEmpty] && [rh isNotNull])
[self registerRequestHandler:rh forKey:rk];
[rh release]; rh = nil;
if ((rh = [[NSClassFromString(@"WOResourceRequestHandler") alloc] init])) {
rk = [WOApplication resourceRequestHandlerKey];
- if ([rk length] > 0)
+ if ([rk isNotEmpty])
[self registerRequestHandler:rh forKey:rk];
[self registerRequestHandler:rh forKey:@"WebServerResources"];
#ifdef __APPLE__
WOSession *sn;
sn = [self createSessionForRequest:[_ctx request]];
- [_ctx setSession:sn];
+ [_ctx setNewSession:sn];
if ([sn respondsToSelector:@selector(prepare)]) {
#if DEBUG
/* first look into form values */
if ((sessionId = [_request formValueForKey:WORequestValueSessionID])!=nil) {
- if ([sessionId length] > 0)
+ if ([sessionId isNotEmpty])
return sessionId;
}
e = [(id)sessionId objectEnumerator];
while ((sessionId = [e nextObject]) != nil) {
- if ([sessionId length] > 0 && ![sessionId isEqual:@"nil"])
+ if ([sessionId isNotEmpty] && ![sessionId isEqual:@"nil"])
return sessionId;
}
}
else {
- if ([sessionId length] > 0 && ![sessionId isEqual:@"nil"])
+ if ([sessionId isNotEmpty] && ![sessionId isEqual:@"nil"])
return sessionId;
}
}
unsigned char buf[20];
sessionCount++;
- sprintf(buf, "%04X%04X%02X%08X",
+ sprintf((char *)buf, "%04X%04X%02X%08X",
[[self number] intValue], getpid(), sessionCount,
(unsigned int)time(NULL));
- wosid = [NSString stringWithCString:buf];
+ wosid = [NSString stringWithCString:(char *)buf];
return wosid;
}
-- (WOSession *)createSessionForRequest:(WORequest *)_request {
+- (id)createSessionForRequest:(WORequest *)_request {
if ([self respondsToSelector:@selector(createSession)]) {
/* call deprecated method */
[self warnWithFormat:@"calling deprecated -createSession .."];
}
}
-- (WOSession *)restoreSessionWithID:(NSString *)_sid
- inContext:(WOContext *)_ctx
-{
+- (id)restoreSessionWithID:(NSString *)_sid inContext:(WOContext *)_ctx {
WOSession *session;
*(&session) = nil;
}
else {
session = [store restoreSessionWithID:_sid request:[_ctx request]];
- if (session) {
+ if ([session isNotNull]) {
[_ctx setSession:session];
[session _awakeWithContext:_ctx];
}
}
}
-- (WOSession *)session {
+- (id)session {
return [[self context] session];
}
return [self handleSessionRestorationError];
}
+ // TODO: is it correct to return nil?
+ // TODO: we should return a page saying sorry with a cookie + redirect
[self errorWithFormat:@"could not restore session for context %@", _ctx];
return nil;
}
/* resources */
+- (void)_setupDefaultResourceManager {
+ NSUserDefaults *ud;
+ Class rmClass;
+ NSString *p;
+
+ ud = [NSUserDefaults standardUserDefaults];
+ p = [ud stringForKey:@"WODefaultResourceManager"];
+ rmClass = [p isNotEmpty]
+ ? NSClassFromString(p)
+ : [WOResourceManager class];
+
+ if (rmClass == Nil) {
+ [self errorWithFormat:
+ @"failed to locate class of resource manager: '%@'", p];
+ return;
+ }
+
+ if ([rmClass instancesRespondToSelector:@selector(initWithPath:)])
+ self->resourceManager = [[rmClass alloc] init];
+ else {
+ self->resourceManager =
+ [(WOResourceManager *)[rmClass alloc] initWithPath:[self path]];
+ }
+}
+
- (void)setResourceManager:(WOResourceManager *)_manager {
ASSIGN(self->resourceManager, _manager);
}
- (WOResourceManager *)resourceManager {
- if (self->resourceManager == nil) {
- NSString *p;
-
-#if 0 && DEBUG
- if ([(p = [self path]) length] > 0)
- [self debugWithFormat:@"setup WOResourceManager at path '%@' ...", p];
-#else
- p = [self path];
-#endif
-
- self->resourceManager =
- [(WOResourceManager *)[WOResourceManager alloc] initWithPath:p];
- }
+ if (self->resourceManager == nil)
+ [self _setupDefaultResourceManager];
+
return self->resourceManager;
}
- (void)awake {
}
- (void)sleep {
+#if DEBUG && PRINT_NSSTRING_STATISTICS
+ if ([NSString respondsToSelector:@selector(printStatistics)])
+ [NSString printStatistics];
+#endif
+
+#if DEBUG && PRINT_OBJC_STATISTICS
+extern int __objc_selector_max_index;
+ printf("nbuckets=%i, nindices=%i, narrays=%i, idxsize=%i\n",
+nbuckets, nindices, narrays, idxsize);
+ printf("maxsel=%i\n", __objc_selector_max_index);
+#endif
}
/* responder */
else {
WOComponent *page;
- if ((page = [_ctx page])) {
+ if ((page = [_ctx page]) != nil) {
WOContext_enterComponent(_ctx, page, nil);
[page takeValuesFromRequest:_req inContext:_ctx];
WOContext_leaveComponent(_ctx, page);
return self->permanentPageCacheSize;
}
-- (WOComponent *)pageWithName:(NSString *)_name {
+- (id)pageWithName:(NSString *)_name {
// deprecated in WO4
return [self pageWithName:_name inContext:[self context]];
}
start = [self memoryStatistics];
#endif
- pool = [[NSAutoreleasePool alloc] init];
+ pool = [[NSAutoreleasePool alloc] init];
- languages = [_ctx hasSession]
- ? [(WOSession *)[_ctx session] languages]
- : [[_ctx request] browserLanguages];
+ languages = [_ctx resourceLookupLanguages];
if ((rm = [[_ctx component] resourceManager]) == nil)
rm = [self resourceManager];
- page = [rm pageWithName:(_name != nil ? _name : @"Main")
- languages:languages];
+ /* TODO:
+ * the following ignores the fact that the passed context may be different
+ * from that of WOApplication. During the course of template instantiation
+ * WOApplication's current context gets attached to page which is definitely
+ * wrong. We workaround this problem by using the private API of WOComponent
+ * to explicitly set it. However all accompanied methods should be
+ * extended to pass the correct context where needed.
+ */
+ page = [rm pageWithName:(_name != nil ? _name : @"Main")
+ languages:languages];
+ [page _setContext:_ctx];
[page ensureAwakeInContext:_ctx];
page = [page retain];
return [page autorelease];
}
-- (WOComponent *)pageWithName:(NSString *)_name inContext:(WOContext *)_ctx {
+- (id)pageWithName:(NSString *)_name inContext:(WOContext *)_ctx {
return [self _pageWithName:_name inContext:_ctx];
}
-- (WOComponent *)pageWithName:(NSString *)_name forRequest:(WORequest *)_req {
+- (id)pageWithName:(NSString *)_name forRequest:(WORequest *)_req {
WOResourceManager *rm;
if ((rm = [self resourceManager]) == nil)
[r setHeader:@"text/html" forKey:@"content-type"];
[r setHeader:@"no-cache" forKey:@"cache-control"];
- if(rapidTurnAroundPath != nil) {
+ if (rapidTurnAroundPath != nil) {
NSURL *templateURL;
templateURL = [[_exc userInfo] objectForKey:@"templateURL"];
static BOOL lookedUpForEOEditingContextClass = NO;
if (!lookedUpForEOEditingContextClass) {
- eoEditingContextClass = NSClassFromString(@"EOEditingContext");
+ if ((eoEditingContextClass = NSClassFromString(@"EOEditingContext")) ==nil)
+ eoEditingContextClass = NSClassFromString(@"NSManagedObjectContext");
lookedUpForEOEditingContextClass = YES;
}
return eoEditingContextClass;