2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE 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 SOPE 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 SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "WODirectActionRequestHandler.h"
23 #include "WORequestHandler+private.h"
24 #include "WOContext+private.h"
25 #include <NGObjWeb/WOApplication.h>
26 #include <NGObjWeb/WOComponent.h>
27 #include <NGObjWeb/WODirectAction.h>
28 #include <NGObjWeb/WORequest.h>
29 #include <NGObjWeb/WOResponse.h>
30 #include <NGObjWeb/WOSession.h>
31 #include <NGObjWeb/WOSessionStore.h>
32 #include <NGObjWeb/WOStatisticsStore.h>
35 #if APPLE_RUNTIME || NeXT_RUNTIME
36 # include <objc/objc-class.h>
39 static BOOL usePool = NO;
40 static BOOL perflog = NO;
41 static BOOL debugOn = NO;
42 static Class NSDateClass = Nil;
44 @implementation WODirectActionRequestHandler
47 return [super version] + 0 /* 2 */;
50 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
52 NSAssert2([super version] == 2,
53 @"invalid superclass (%@) version %i !",
54 NSStringFromClass([self superclass]), [super version]);
56 NSDateClass = [NSDate class];
57 perflog = [ud boolForKey:@"WOProfileDirectActionRequestHandler"];
60 - (NSString *)loggingPrefix {
61 return @"[da-handler]";
65 The request handler part of a direct action URI looks like this:
67 [actionClass/]actionName[?key=value&key=value&...]
70 - (BOOL)isComponentClass:(Class)_clazz {
73 while ((_clazz = _clazz->super_class) != Nil) {
74 if (_clazz == [WOComponent class]) return YES;
75 if (_clazz == [WODirectAction class]) return NO;
76 if (_clazz == [NSObject class]) return NO;
81 - (id)instantiateObjectForActionClass:(Class)actionClass
82 inContext:(WOContext *)context
83 application:(WOApplication *)app
85 WOComponent *component;
87 if (actionClass == Nil)
90 if (![self isComponentClass:actionClass]) {
91 /* create direct action object */
94 if (![actionClass instancesRespondToSelector:
95 @selector(initWithContext:)]) {
96 [self logWithFormat:@"tried to use class '%@' as a direct-action class",
97 NSStringFromClass(actionClass)];
102 [(WODirectAction *)[actionClass alloc] initWithContext:context];
103 actionObject = [actionObject autorelease];
107 /* special initialization for WOComponents used as direct actions */
109 component = [app pageWithName:NSStringFromClass(actionClass)
111 [context setPage:(id)component];
113 /* TODO: why was that commented out? */
114 if ([component shouldTakeValuesFromRequest:[context request]
116 [app takeValuesFromRequest:[context request] inContext:context];
121 - (WOResponse *)handleRequest:(WORequest *)_request
122 inContext:(WOContext *)context
123 session:(WOSession *)session
124 application:(WOApplication *)app
126 NSAutoreleasePool *pool2;
127 NSString *actionClassName;
128 NSString *actionName;
129 WOResponse *response;
130 NSArray *handlerPath;
131 Class actionClass = Nil;
132 WODirectAction *actionObject = nil;
133 id<WOActionResults> result = nil;
135 pool2 = usePool ? [[NSAutoreleasePool alloc] init] : nil;
139 *(&actionClassName) = nil;
140 *(&actionName) = nil;
141 *(&handlerPath) = nil;
145 handlerPath = [_request requestHandlerPathArray];
148 [self debugWithFormat:@"path=%@ array=%@",
149 [_request requestHandlerPath], handlerPath];
152 // TODO: fix OGo bug #1028
153 switch ([handlerPath count]) {
155 actionClassName = @"DirectAction";
156 actionName = @"default";
159 actionClassName = @"DirectAction";
160 actionName = [handlerPath objectAtIndex:0];
163 actionClassName = [handlerPath objectAtIndex:0];
164 actionName = [handlerPath objectAtIndex:1];
168 actionClassName = [handlerPath objectAtIndex:0];
169 actionName = [handlerPath objectAtIndex:1];
170 // TODO: set path info in ctx?
172 [self logWithFormat:@"invalid direction action URL: %@",
173 [_request requestHandlerPath]];
178 if ([actionName length] == 0)
179 actionName = @"default";
181 if ((*(&actionClass) = NSClassFromString(actionClassName)) == Nil) {
182 [self errorWithFormat:@"did not find direct action class %@",
184 actionClass = [WODirectAction class];
188 [self debugWithFormat:
189 @"[direct action request handler] class=%@ action=%@ ..",
190 actionClassName, actionName];
193 /* process request */
195 actionObject = [self instantiateObjectForActionClass:actionClass
199 if (actionObject == nil) {
200 [self errorWithFormat:
201 @"could not create direct action object of class %@",
206 static Class WOComponentClass = Nil;
208 if (WOComponentClass == Nil)
209 WOComponentClass = [WOComponent class];
211 result = [(id)[actionObject performActionNamed:actionName] retain];
213 if (result == nil) result = [[context page] retain];
215 if ([(id)result isKindOfClass:WOComponentClass]) {
216 [(id)result _awakeWithContext:context];
217 [context setPage:(WOComponent *)result];
219 response = [self generateResponseForComponent:(WOComponent *)result
223 if ([context hasSession]) {
224 if ([context savePageRequired])
225 [[context session] savePage:(WOComponent *)result];
228 response = [response retain];
231 /* generate response */
232 response = [[result generateResponse] retain];
235 [context sleepComponents];
237 [(id)result release]; result = nil;
239 /* check whether a session was created */
240 if ((session == nil) && [context hasSession]) {
241 session = [[[context session] retain] autorelease];
246 session = [session retain];
247 [pool2 release]; pool2 = nil;
248 session = [session autorelease];
250 response = [response autorelease];
256 @end /* WODirectActionRequestHandler */