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 <NGObjWeb/OWViewRequestHandler.h>
23 #include "WORequestHandler+private.h"
24 #include "WOContext+private.h"
25 #include "WOComponent+private.h"
26 #include "WOApplication+private.h"
27 #include <NGObjWeb/WOComponent.h>
28 #include <NGObjWeb/WORequest.h>
29 #include <NGObjWeb/WOResponse.h>
30 #include <NGObjWeb/WOSessionStore.h>
31 #include <NGObjWeb/WOSession.h>
34 NSString *OWAppDidRefuseSessionName = @"OWAppDidRefuseSession";
35 static BOOL perflog = NO;
40 # warning extensive pools are enabled ...
43 @implementation OWViewRequestHandler
46 return [super version] + 0 /* 2 */;
49 NSAssert2([super version] == 2,
50 @"invalid superclass (%@) version %i !",
51 NSStringFromClass([self superclass]), [super version]);
53 perflog = [[NSUserDefaults standardUserDefaults]
54 boolForKey:@"OWViewRequestHandlerProfile"];
57 - (NSString *)loggingPrefix {
58 return @"[ow-handler]";
62 //NSLog(@"DEPRECATED: OWViewRequestHandler is being allocated ...");
66 - (WOResponse *)runTransactionWithContext:(WOContext *)_ctx {
67 WOApplication *app = nil;
69 WOResponse *response = nil;
70 id<NSObject,WOActionResults> result;
72 app = [_ctx application];
74 NSAssert(_ctx != nil, @"no context available");
75 NSAssert(sn != nil, @"no session available");
76 NSAssert(app != nil, @"no application available in context");
78 /* take request values */
80 [app takeValuesFromRequest:[_ctx request] inContext:_ctx];
84 result = [app invokeActionForRequest:[_ctx request] inContext:_ctx];
86 /* check whether there is an page set at all ! */
88 if ([_ctx page] == nil) {
89 /* no page is set yet, load Main .. */
90 WOComponent *mainPage;
92 if ((mainPage = [app pageWithName:nil inContext:_ctx])) {
93 [_ctx setPage:mainPage];
94 [mainPage _awakeWithContext:_ctx];
100 if ((result == nil) || [result isKindOfClass:[WOComponent class]]) {
101 /* determine the response page */
104 /* make the request page the response page */
105 if ((result = [_ctx page]) == nil) {
106 /* no request page (probably the first request) */
107 result = [app pageWithName:nil inContext:_ctx];
108 [(id)result _awakeWithContext:_ctx];
109 [_ctx setPage:(WOComponent *)result];
113 response = [self generateResponseForComponent:(WOComponent *)result
117 /* save page in session */
119 if ([_ctx savePageRequired]) {
120 [sn savePage:[_ctx page]];
122 [self logWithFormat:@"saved page ..."];
127 [self logWithFormat:@"no save page required ..."];
132 /* generate response from WOActionResult */
133 if ([result respondsToSelector:@selector(generateResponse)]) {
134 [app debugWithFormat:@"generating response for result .."];
135 response = [result generateResponse];
139 @"action result (class=%@) doesn't conform to "
140 @"WOActionResult protocol !",
141 NSStringFromClass([result class])];
143 response = [[WOResponse alloc] init];
144 [response setStatus:200];
145 [response appendContentString:@"<pre>"];
146 [response appendContentHTMLString:
148 @"Result of action doesn't conform to WOActionResult "
151 [response appendContentHTMLString:
152 [NSStringFromClass([result class]) description]];
153 [response appendContentHTMLString:@"\nContent:\n"];
154 [response appendContentHTMLString:[result description]];
155 [response appendContentString:@"</pre>\n"];
156 AUTORELEASE(response);
160 [_ctx sleepComponents];
165 - (NSString *)sessionIDFromRequest:(WORequest *)_request
166 application:(WOApplication *)_app
168 NSString *sessionId = nil;
171 if ((tmp = [_request formValueForKey:WORequestValueSenderID]) == nil) {
172 if ([[_request requestHandlerPath] length] > 0) {
173 /* traditional style URLs */
176 spath = [_request requestHandlerPathArray];
177 if ([spath count] > 0)
178 sessionId = [spath objectAtIndex:0];
182 if ([sessionId length] == 0)
183 sessionId = [_app sessionIDFromRequest:_request];
188 - (BOOL)autocreateSessionForRequest:(WORequest *)_request {
189 /* autocreate a session if none was restored */
192 - (BOOL)requiresSessionForRequest:(WORequest *)_request {
193 /* _ensure_ that a session is available */
197 - (WOResponse *)handleRequest:(WORequest *)_request
198 inContext:(WOContext *)context
199 session:(WOSession *)session
200 application:(WOApplication *)app
202 NSString *requestContextID;
203 WOResponse *response;
204 WOComponent *requestComponent;
206 NSTimeInterval startRunTx = 0.0;
209 *(&requestContextID) = nil;
211 *(&requestComponent) = nil;
213 NSAssert(session, @"no session given !");
216 parse handler path (URL)
219 session/context-id.element-id
222 pageName?_i=context-id.element-id&wosid=session&_c=context-id
225 if ((tmp = [_request formValueForKey:WORequestValueSenderID])) {
226 /* new query-para style URL */
227 [context setRequestSenderID:tmp];
229 if ((tmp = [_request formValueForKey:WORequestValueContextID]))
230 requestContextID = tmp;
232 requestContextID = [context currentElementID];
234 else if ([[_request requestHandlerPath] length] > 0) {
235 /* traditional style URLs */
238 spath = [_request requestHandlerPathArray];
240 if ([spath count] > 1) {
241 [context setRequestSenderID:[spath objectAtIndex:1]];
242 requestContextID = [context currentElementID];
244 // at idx 0 => sessionId
247 /* determine request component */
249 if ([[self sessionIDFromRequest:_request application:app]
250 isEqualToString:[session sessionID]])
251 cid = [context currentElementID];
253 /* the session is different, was autocreated ... */
256 if ((session != nil) && ([cid length] > 0)) {
257 requestComponent = [session restorePageForContextID:cid];
259 if (requestComponent == nil) {
260 /* could not restore page ... */
261 response = [app handlePageRestorationErrorInContext:context];
264 @"returning because of page restoration error ..."];
269 if (requestComponent) {
270 [context setPage:requestComponent];
271 [requestComponent _awakeWithContext:context];
274 /* run transaction */
277 startRunTx = [[NSDate date] timeIntervalSince1970];
279 response = [self runTransactionWithContext:context];
283 rt = [[NSDate date] timeIntervalSince1970] - startRunTx;
284 [self logWithFormat:@"running tx took %4.3fs.", rt < 0.0 ? -1.0 : rt];
290 @end /* OWViewRequestHandler */