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
23 #include <NGObjWeb/OWViewRequestHandler.h>
24 #include "WORequestHandler+private.h"
25 #include "WOContext+private.h"
26 #include "WOComponent+private.h"
27 #include "WOApplication+private.h"
28 #include <NGObjWeb/WOComponent.h>
29 #include <NGObjWeb/WORequest.h>
30 #include <NGObjWeb/WOResponse.h>
31 #include <NGObjWeb/WOSessionStore.h>
32 #include <NGObjWeb/WOSession.h>
35 NSString *OWAppDidRefuseSessionName = @"OWAppDidRefuseSession";
36 static BOOL perflog = NO;
41 # warning extensive pools are enabled ...
44 @implementation OWViewRequestHandler
47 return [super version] + 0 /* 2 */;
50 NSAssert2([super version] == 2,
51 @"invalid superclass (%@) version %i !",
52 NSStringFromClass([self superclass]), [super version]);
54 perflog = [[NSUserDefaults standardUserDefaults]
55 boolForKey:@"OWViewRequestHandlerProfile"];
58 - (NSString *)loggingPrefix {
59 return @"[ow-handler]";
63 //NSLog(@"DEPRECATED: OWViewRequestHandler is being allocated ...");
67 - (WOResponse *)runTransactionWithContext:(WOContext *)_ctx {
68 WOApplication *app = nil;
70 WOResponse *response = nil;
71 id<NSObject,WOActionResults> result;
73 app = [_ctx application];
75 NSAssert(_ctx != nil, @"no context available");
76 NSAssert(sn != nil, @"no session available");
77 NSAssert(app != nil, @"no application available in context");
79 /* take request values */
81 [app takeValuesFromRequest:[_ctx request] inContext:_ctx];
85 result = [app invokeActionForRequest:[_ctx request] inContext:_ctx];
87 /* check whether there is an page set at all ! */
89 if ([_ctx page] == nil) {
90 /* no page is set yet, load Main .. */
91 WOComponent *mainPage;
93 if ((mainPage = [app pageWithName:nil inContext:_ctx])) {
94 [_ctx setPage:mainPage];
95 [mainPage _awakeWithContext:_ctx];
101 if ((result == nil) || [result isKindOfClass:[WOComponent class]]) {
102 /* determine the response page */
105 /* make the request page the response page */
106 if ((result = [_ctx page]) == nil) {
107 /* no request page (probably the first request) */
108 result = [app pageWithName:nil inContext:_ctx];
109 [(id)result _awakeWithContext:_ctx];
110 [_ctx setPage:(WOComponent *)result];
114 response = [self generateResponseForComponent:(WOComponent *)result
118 /* save page in session */
120 if ([_ctx savePageRequired]) {
121 [sn savePage:[_ctx page]];
123 [self logWithFormat:@"saved page ..."];
128 [self logWithFormat:@"no save page required ..."];
133 /* generate response from WOActionResult */
134 if ([result respondsToSelector:@selector(generateResponse)]) {
135 [app debugWithFormat:@"generating response for result .."];
136 response = [result generateResponse];
140 @"action result (class=%@) doesn't conform to "
141 @"WOActionResult protocol !",
142 NSStringFromClass([result class])];
144 response = [[WOResponse alloc] init];
145 [response setStatus:200];
146 [response appendContentString:@"<pre>"];
147 [response appendContentHTMLString:
149 @"Result of action doesn't conform to WOActionResult "
152 [response appendContentHTMLString:
153 [NSStringFromClass([result class]) description]];
154 [response appendContentHTMLString:@"\nContent:\n"];
155 [response appendContentHTMLString:[result description]];
156 [response appendContentString:@"</pre>\n"];
157 AUTORELEASE(response);
161 [_ctx sleepComponents];
166 - (NSString *)sessionIDFromRequest:(WORequest *)_request
167 application:(WOApplication *)_app
169 NSString *sessionId = nil;
172 if ((tmp = [_request formValueForKey:WORequestValueSenderID]) == nil) {
173 if ([[_request requestHandlerPath] length] > 0) {
174 /* traditional style URLs */
177 spath = [_request requestHandlerPathArray];
178 if ([spath count] > 0)
179 sessionId = [spath objectAtIndex:0];
183 if ([sessionId length] == 0)
184 sessionId = [_app sessionIDFromRequest:_request];
189 - (BOOL)autocreateSessionForRequest:(WORequest *)_request {
190 /* autocreate a session if none was restored */
193 - (BOOL)requiresSessionForRequest:(WORequest *)_request {
194 /* _ensure_ that a session is available */
198 - (WOResponse *)handleRequest:(WORequest *)_request
199 inContext:(WOContext *)context
200 session:(WOSession *)session
201 application:(WOApplication *)app
203 NSString *requestContextID;
204 WOResponse *response;
205 WOComponent *requestComponent;
207 NSTimeInterval startRunTx = 0.0;
210 *(&requestContextID) = nil;
212 *(&requestComponent) = nil;
214 NSAssert(session, @"no session given !");
217 parse handler path (URL)
220 session/context-id.element-id
223 pageName?_i=context-id.element-id&wosid=session&_c=context-id
226 if ((tmp = [_request formValueForKey:WORequestValueSenderID])) {
227 /* new query-para style URL */
228 [context setRequestSenderID:tmp];
230 if ((tmp = [_request formValueForKey:WORequestValueContextID]))
231 requestContextID = tmp;
233 requestContextID = [context currentElementID];
235 else if ([[_request requestHandlerPath] length] > 0) {
236 /* traditional style URLs */
239 spath = [_request requestHandlerPathArray];
241 if ([spath count] > 1) {
242 [context setRequestSenderID:[spath objectAtIndex:1]];
243 requestContextID = [context currentElementID];
245 // at idx 0 => sessionId
248 /* determine request component */
250 if ([[self sessionIDFromRequest:_request application:app]
251 isEqualToString:[session sessionID]])
252 cid = [context currentElementID];
254 /* the session is different, was autocreated ... */
257 if ((session != nil) && ([cid length] > 0)) {
258 requestComponent = [session restorePageForContextID:cid];
260 if (requestComponent == nil) {
261 /* could not restore page ... */
262 response = [app handlePageRestorationErrorInContext:context];
265 @"returning because of page restoration error ..."];
270 if (requestComponent) {
271 [context setPage:requestComponent];
272 [requestComponent _awakeWithContext:context];
275 /* run transaction */
278 startRunTx = [[NSDate date] timeIntervalSince1970];
280 response = [self runTransactionWithContext:context];
284 rt = [[NSDate date] timeIntervalSince1970] - startRunTx;
285 [self logWithFormat:@"running tx took %4.3fs.", rt < 0.0 ? -1.0 : rt];
291 @end /* OWViewRequestHandler */