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 if ([component shouldTakeValuesFromRequest:[context request]
115 [app takeValuesFromRequest:[context request] inContext:context];
120 - (WOResponse *)handleRequest:(WORequest *)_request
121 inContext:(WOContext *)context
122 session:(WOSession *)session
123 application:(WOApplication *)app
125 NSAutoreleasePool *pool2;
126 NSString *actionClassName;
127 NSString *actionName;
128 WOResponse *response;
129 NSArray *handlerPath;
130 Class actionClass = Nil;
131 WODirectAction *actionObject = nil;
132 id<WOActionResults> result = nil;
134 pool2 = usePool ? [[NSAutoreleasePool alloc] init] : nil;
138 *(&actionClassName) = nil;
139 *(&actionName) = nil;
140 *(&handlerPath) = nil;
144 handlerPath = [_request requestHandlerPathArray];
147 [self debugWithFormat:@"path=%@ array=%@",
148 [_request requestHandlerPath], handlerPath];
151 // TODO: fix OGo bug #1028
152 switch ([handlerPath count]) {
154 actionClassName = @"DirectAction";
155 actionName = @"default";
158 actionClassName = @"DirectAction";
159 actionName = [handlerPath objectAtIndex:0];
162 actionClassName = [handlerPath objectAtIndex:0];
163 actionName = [handlerPath objectAtIndex:1];
167 actionClassName = [handlerPath objectAtIndex:0];
168 actionName = [handlerPath objectAtIndex:1];
169 // TODO: set path info in ctx?
171 [self logWithFormat:@"invalid direction action URL: %@",
172 [_request requestHandlerPath]];
177 if ([actionName length] == 0)
178 actionName = @"default";
180 if ((*(&actionClass) = NSClassFromString(actionClassName)) == Nil) {
181 [self errorWithFormat:@"did not find direct action class %@",
183 actionClass = [WODirectAction class];
187 [self debugWithFormat:
188 @"[direct action request handler] class=%@ action=%@ ..",
189 actionClassName, actionName];
192 /* process request */
194 actionObject = [self instantiateObjectForActionClass:actionClass
198 if (actionObject == nil) {
199 [self errorWithFormat:
200 @"could not create direct action object of class %@",
205 static Class WOComponentClass = Nil;
207 if (WOComponentClass == Nil)
208 WOComponentClass = [WOComponent class];
210 result = [(id)[actionObject performActionNamed:actionName] retain];
212 if (result == nil) result = [[context page] retain];
214 if ([(id)result isKindOfClass:WOComponentClass]) {
215 [(id)result _awakeWithContext:context];
216 [context setPage:(WOComponent *)result];
218 response = [self generateResponseForComponent:(WOComponent *)result
222 if ([context hasSession]) {
223 if ([context savePageRequired])
224 [[context session] savePage:(WOComponent *)result];
227 response = [response retain];
230 /* generate response */
231 response = [[result generateResponse] retain];
234 [context sleepComponents];
236 [(id)result release]; result = nil;
238 /* check whether a session was created */
239 if ((session == nil) && [context hasSession]) {
240 session = [[[context session] retain] autorelease];
245 session = [session retain];
246 [pool2 release]; pool2 = nil;
247 session = [session autorelease];
249 response = [response autorelease];
255 @end /* WODirectActionRequestHandler */