2 Copyright (C) 2000-2004 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 "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 perflog = NO;
40 static Class NSDateClass = Nil;
44 @implementation WODirectActionRequestHandler
47 return [super version] + 0 /* 2 */;
50 NSAssert2([super version] == 2,
51 @"invalid superclass (%@) version %i !",
52 NSStringFromClass([self superclass]), [super version]);
54 NSDateClass = [NSDate class];
55 perflog = [[NSUserDefaults standardUserDefaults]
56 boolForKey:@"WOProfileDirectActionRequestHandler"];
59 - (NSString *)loggingPrefix {
60 return @"[da-handler]";
64 The request handler part of a direct action URI looks like this:
66 [actionClass/]actionName[?key=value&key=value&...]
69 - (BOOL)isComponentClass:(Class)_clazz {
72 while ((_clazz = _clazz->super_class)) {
73 if (_clazz == [WOComponent class]) return YES;
74 if (_clazz == [WODirectAction class]) return NO;
75 if (_clazz == [NSObject class]) return NO;
80 - (id)instantiateObjectForActionClass:(Class)actionClass
81 inContext:(WOContext *)context
82 application:(WOApplication *)app
84 WOComponent *component;
86 if (actionClass == Nil)
88 if (![self isComponentClass:actionClass]) {
89 /* create direct action object */
92 if (![actionClass instancesRespondToSelector:
93 @selector(initWithContext:)]) {
94 [self logWithFormat:@"tried to use class '%@' as a direct-action class",
95 NSStringFromClass(actionClass)];
100 [(WODirectAction *)[actionClass alloc] initWithContext:context];
101 actionObject = [actionObject autorelease];
105 /* special initialization for WOComponents used as direct actions */
107 component = [app pageWithName:NSStringFromClass(actionClass)
109 [context setPage:(id)component];
111 /* TODO: why was that commented out? */
112 if ([component shouldTakeValuesFromRequest:[context request]
114 [app takeValuesFromRequest:[context request] inContext:context];
119 - (WOResponse *)handleRequest:(WORequest *)_request
120 inContext:(WOContext *)context
121 session:(WOSession *)session
122 application:(WOApplication *)app
125 NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];
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;
137 *(&actionClassName) = nil;
138 *(&actionName) = nil;
139 *(&handlerPath) = nil;
143 handlerPath = [_request requestHandlerPathArray];
145 #if DEBUG_DIRECT_ACTION
146 [self debugWithFormat:@"path=%@ array=%@",
147 [_request requestHandlerPath], handlerPath];
150 switch ([handlerPath count]) {
152 actionClassName = @"DirectAction";
153 actionName = @"default";
156 actionClassName = @"DirectAction";
157 actionName = [handlerPath objectAtIndex:0];
160 actionClassName = [handlerPath objectAtIndex:0];
161 actionName = [handlerPath objectAtIndex:1];
165 actionClassName = [handlerPath objectAtIndex:0];
166 actionName = [handlerPath objectAtIndex:1];
168 NSLog(@"invalid direction action URL: %@",
169 [_request requestHandlerPath]);
174 if ([actionName length] == 0)
175 actionName = @"default";
177 if ((*(&actionClass) = NSClassFromString(actionClassName)) == Nil) {
178 [self logWithFormat:@"ERROR: did not find direct action class %@",
180 actionClass = [WODirectAction class];
183 #if DEBUG_DIRECT_ACTION
184 [self debugWithFormat:
185 @"[direct action request handler] class=%@ action=%@ ..",
186 actionClassName, actionName];
189 /* process request */
191 actionObject = [self instantiateObjectForActionClass:actionClass
195 if (actionObject == nil) {
197 @"ERROR: could not create direct action object of class %@",
202 static Class WOComponentClass = Nil;
204 if (WOComponentClass == Nil)
205 WOComponentClass = [WOComponent class];
207 result = [(id)[actionObject performActionNamed:actionName] retain];
209 if (result == nil) result = [[context page] retain];
211 if ([(id)result isKindOfClass:WOComponentClass]) {
212 [(id)result _awakeWithContext:context];
213 [context setPage:(WOComponent *)result];
215 response = [self generateResponseForComponent:(WOComponent *)result
219 if ([context hasSession]) {
220 if ([context savePageRequired])
221 [[context session] savePage:(WOComponent *)result];
224 response = [response retain];
227 /* generate response */
228 response = [[result generateResponse] retain];
231 [context sleepComponents];
233 [(id)result release]; result = nil;
235 /* check whether a session was created */
236 if ((session == nil) && [context hasSession]) {
237 session = [[[context session] retain] autorelease];
242 session = [session retain];
243 [pool2 release]; pool2 = nil;
244 session = [session autorelease];
246 response = [response autorelease];
252 @end /* WODirectActionRequestHandler */