]> err.no Git - sope/blob - sope-appserver/NGObjWeb/OWViewRequestHandler.m
renamed packages as discussed in the developer list
[sope] / sope-appserver / NGObjWeb / OWViewRequestHandler.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21 // $Id$
22
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>
33 #include "common.h"
34
35 NSString *OWAppDidRefuseSessionName = @"OWAppDidRefuseSession";
36 static BOOL perflog = NO;
37
38 //#define USE_POOLS 1
39
40 #if USE_POOLS
41 #  warning extensive pools are enabled ...
42 #endif
43
44 @implementation OWViewRequestHandler
45
46 + (int)version {
47   return [super version] + 0 /* 2 */;
48 }
49 + (void)initialize {
50   NSAssert2([super version] == 2,
51             @"invalid superclass (%@) version %i !",
52             NSStringFromClass([self superclass]), [super version]);
53   
54   perflog = [[NSUserDefaults standardUserDefaults]
55                              boolForKey:@"OWViewRequestHandlerProfile"];
56 }
57
58 - (NSString *)loggingPrefix {
59   return @"[ow-handler]";
60 }
61
62 - (id)init {
63   //NSLog(@"DEPRECATED: OWViewRequestHandler is being allocated ...");
64   return [super init];
65 }
66
67 - (WOResponse *)runTransactionWithContext:(WOContext *)_ctx {
68   WOApplication *app      = nil;
69   WOSession     *sn       = nil;
70   WOResponse    *response = nil;
71   id<NSObject,WOActionResults> result;
72   
73   app = [_ctx application];
74   sn  = [_ctx session];
75   NSAssert(_ctx != nil, @"no context available");
76   NSAssert(sn   != nil, @"no session available");
77   NSAssert(app  != nil, @"no application available in context");
78
79   /* take request values */
80
81   [app takeValuesFromRequest:[_ctx request] inContext:_ctx];
82
83   /* invoke action */
84     
85   result = [app invokeActionForRequest:[_ctx request] inContext:_ctx];
86     
87   /* check whether there is an page set at all ! */
88
89   if ([_ctx page] == nil) {
90     /* no page is set yet, load Main .. */
91     WOComponent *mainPage;
92
93     if ((mainPage = [app pageWithName:nil inContext:_ctx])) {
94       [_ctx setPage:mainPage];
95       [mainPage _awakeWithContext:_ctx];
96     }
97   }
98   
99   /* make response */
100   
101   if ((result == nil) || [result isKindOfClass:[WOComponent class]]) {
102     /* determine the response page */
103       
104     if (result == nil) {
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];
111       }
112     }
113
114     response = [self generateResponseForComponent:(WOComponent *)result
115                      inContext:_ctx
116                      application:app];
117       
118     /* save page in session */
119       
120     if ([_ctx savePageRequired]) {
121       [sn savePage:[_ctx page]];
122 #if DEBUG && 0
123       [self logWithFormat:@"saved page ..."];
124 #endif
125     }
126 #if DEBUG && 0
127     else {
128       [self logWithFormat:@"no save page required ..."];
129     }
130 #endif
131   }
132   else {
133     /* generate response from WOActionResult */
134     if ([result respondsToSelector:@selector(generateResponse)]) {
135       [app debugWithFormat:@"generating response for result .."];
136       response = [result generateResponse];
137     }
138     else {
139       [app logWithFormat:
140              @"action result (class=%@) doesn't conform to "
141              @"WOActionResult protocol !",
142              NSStringFromClass([result class])];
143         
144       response = [[WOResponse alloc] init];
145       [response setStatus:200];
146       [response appendContentString:@"<pre>"];
147       [response appendContentHTMLString:
148                   @"ERROR:\n"
149                   @"Result of action doesn't conform to WOActionResult "
150                   @"protocol:\n---\n"
151                   @"Content-Class: "];
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);
158     }
159   }
160     
161   [_ctx sleepComponents];
162     
163   return response;
164 }
165
166 - (NSString *)sessionIDFromRequest:(WORequest *)_request
167   application:(WOApplication *)_app
168 {
169   NSString *sessionId = nil;
170   id tmp;
171   
172   if ((tmp = [_request formValueForKey:WORequestValueSenderID]) == nil) {
173     if ([[_request requestHandlerPath] length] > 0) {
174       /* traditional style URLs */
175       NSArray *spath;
176       
177       spath = [_request requestHandlerPathArray];
178       if ([spath count] > 0)
179         sessionId = [spath objectAtIndex:0];
180     }
181   }
182   
183   if ([sessionId length] == 0)
184     sessionId = [_app sessionIDFromRequest:_request];
185   
186   return sessionId;
187 }
188
189 - (BOOL)autocreateSessionForRequest:(WORequest *)_request {
190   /* autocreate a session if none was restored */
191   return YES;
192 }
193 - (BOOL)requiresSessionForRequest:(WORequest *)_request {
194   /* _ensure_ that a session is available */
195   return YES;
196 }
197
198 - (WOResponse *)handleRequest:(WORequest *)_request
199   inContext:(WOContext *)context
200   session:(WOSession *)session
201   application:(WOApplication *)app
202 {
203   NSString       *requestContextID;
204   WOResponse     *response;
205   WOComponent    *requestComponent;
206   NSString       *cid;
207   NSTimeInterval startRunTx = 0.0;
208   id tmp;
209
210   *(&requestContextID) = nil;
211   *(&response)         = nil;
212   *(&requestComponent) = nil;
213   
214   NSAssert(session, @"no session given !");
215
216   /*
217     parse handler path (URL)
218       
219     The format is:
220       session/context-id.element-id
221       
222     or
223       pageName?_i=context-id.element-id&wosid=session&_c=context-id
224   */
225   
226   if ((tmp = [_request formValueForKey:WORequestValueSenderID])) {
227     /* new query-para style URL */
228     [context setRequestSenderID:tmp];
229     
230     if ((tmp = [_request formValueForKey:WORequestValueContextID]))
231       requestContextID = tmp;
232     else
233       requestContextID = [context currentElementID];
234   }
235   else if ([[_request requestHandlerPath] length] > 0) {
236     /* traditional style URLs */
237     NSArray *spath;
238     
239     spath = [_request requestHandlerPathArray];
240       
241     if ([spath count] > 1) {
242       [context setRequestSenderID:[spath objectAtIndex:1]];
243       requestContextID = [context currentElementID];
244     }
245     // at idx 0 => sessionId
246   }
247   
248   /* determine request component */
249
250   if ([[self sessionIDFromRequest:_request application:app]
251              isEqualToString:[session sessionID]])
252     cid = [context currentElementID];
253   else
254     /* the session is different, was autocreated ... */
255     cid = nil;
256   
257   if ((session != nil) && ([cid length] > 0)) {
258     requestComponent = [session restorePageForContextID:cid];
259     
260     if (requestComponent == nil) {
261       /* could not restore page ... */
262       response = [app handlePageRestorationErrorInContext:context];
263       if (response) {
264         [self logWithFormat:
265                 @"returning because of page restoration error ..."];
266         return response;
267       }
268     }
269   }
270   if (requestComponent) {
271     [context setPage:requestComponent];
272     [requestComponent _awakeWithContext:context];
273   }
274   
275   /* run transaction */
276
277   if (perflog)
278     startRunTx = [[NSDate date] timeIntervalSince1970];
279   
280   response = [self runTransactionWithContext:context];
281   
282   if (perflog) {
283     NSTimeInterval rt;
284     rt = [[NSDate date] timeIntervalSince1970] - startRunTx;
285     [self logWithFormat:@"running tx took %4.3fs.", rt < 0.0 ? -1.0 : rt];
286   }
287   
288   return response;
289 }
290
291 @end /* OWViewRequestHandler */