]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WOPageRequestHandler.m
fixed makefiles to search FHS locations at the last resort
[sope] / sope-appserver / NGObjWeb / WOPageRequestHandler.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
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/WORequestHandler.h>
24
25 @interface WOPageRequestHandler : WORequestHandler
26 @end
27
28 //#include "WOPageRequestHandler.h"
29 #include "WORequestHandler+private.h"
30 #include "WOContext+private.h"
31 #include <NGObjWeb/WOApplication.h>
32 #include <NGObjWeb/WOComponent.h>
33 #include <NGObjWeb/WODirectAction.h>
34 #include <NGObjWeb/WORequest.h>
35 #include <NGObjWeb/WOResponse.h>
36 #include <NGObjWeb/WOSession.h>
37 #include <NGObjWeb/WOComponent.h>
38 #include <NGObjWeb/WOSessionStore.h>
39 #include <NGObjWeb/WOStatisticsStore.h>
40 #include "common.h"
41
42 static BOOL  perflog             = NO;
43 static Class NSDateClass         = Nil;
44 static BOOL  debugUnknownActions = NO;
45 static BOOL  debugOn             = NO;
46
47 @interface WOComponent(Privates)
48 - (void)_awakeWithContext:(WOContext *)_ctx;
49 - (id<WOActionResults>)performActionNamed:(NSString *)_actionName;
50 @end
51
52 @implementation WOPageRequestHandler
53
54 + (int)version {
55   return [super version] + 0 /* 2 */;
56 }
57 + (void)initialize {
58   NSUserDefaults *ud;
59   NSAssert2([super version] == 2,
60             @"invalid superclass (%@) version %i !",
61             NSStringFromClass([self superclass]), [super version]);
62
63   NSDateClass = [NSDate class];
64   ud = [NSUserDefaults standardUserDefaults];
65   perflog = [ud boolForKey:@"WOProfilePageRequestHandler"];
66   debugOn = [ud boolForKey:@"WOPageRequestHandlerDebugEnabled"];
67 }
68
69 /* debugging */
70
71 - (NSString *)loggingPrefix {
72   return @"[pg-handler]";
73 }
74 - (BOOL)isDebuggingEnabled {
75   return debugOn;
76 }
77
78 /*
79   The request handler part of a direct action URI looks like this:
80
81     [actionClass/]actionName[?key=value&key=value&...]
82 */
83
84 - (WOResponse *)handleRequest:(WORequest *)_request
85   inContext:(WOContext *)context
86   session:(WOSession *)session
87   application:(WOApplication *)app
88 {
89   NSString      *actionName;
90   WOResponse    *response;
91   id<WOActionResults> result = nil;
92   NSString      *pageName;
93   WOComponent   *page;
94   
95   *(&result) = nil;
96   *(&response)        = nil;
97   *(&actionName)      = nil;
98   
99   /* process path */
100   if ((pageName = [_request headerForKey:@"x-httpd-pagename"]) == nil) {
101     NSArray *handlerPath;
102     
103     handlerPath = [_request requestHandlerPathArray];
104     switch ([handlerPath count]) {
105       case 0:
106         pageName   = @"Main";
107         actionName = @"default";
108         break;
109       case 1:
110         pageName   = [handlerPath objectAtIndex:0];
111         actionName = @"default";
112         break;
113       default:
114         pageName   = [handlerPath objectAtIndex:0];
115         actionName = [handlerPath objectAtIndex:1];
116         break;
117     }
118     
119     if (debugOn) {
120       [self debugWithFormat:@"path:   %@",   handlerPath];
121       [self debugWithFormat:@"page:   %@",   pageName];
122       [self debugWithFormat:@"action: %@", actionName];
123     }
124   }
125   else {
126     if (debugOn)
127       [self debugWithFormat:@"using httpd provided pagename: %@", pageName];
128   }
129   
130   if (pageName == nil)
131     pageName = @"Main";
132   
133   if ((page = [app pageWithName:pageName inContext:context]) == nil) {
134     [self logWithFormat:
135             @"ERROR: could not create page object with name %@", pageName];
136     return nil;
137   }
138   
139   [self debugWithFormat:@"created page: %@", page];
140   
141   /* setup page context */
142   [page _awakeWithContext:context];
143   [context setPage:page];
144   
145   /* take values phase */
146   
147   [app takeValuesFromRequest:_request inContext:context];
148   
149   /* perform a direct action like action */
150   
151   result = [page performActionNamed:actionName];
152
153   /* generate response */
154   
155   if (result != page && result != nil) {
156     if ([(id)result isKindOfClass:[WOComponent class]]) {
157       [(WOComponent *)result _awakeWithContext:context];
158       [context setPage:(WOComponent *)result];
159       
160       response = [self generateResponseForComponent:(WOComponent *)result
161                        inContext:context
162                        application:app];
163     }
164     else
165       response = [result generateResponse];
166   }
167   else {
168     result = page;
169     response = [self generateResponseForComponent:page
170                      inContext:context
171                      application:app];
172   }
173   
174   if ([context hasSession]) {
175     if ([context savePageRequired])
176       [[context session] savePage:(WOComponent *)result];
177   }
178   
179   /* check whether a session was created */
180   if ((session == nil) && [context hasSession]) {
181     session = [[[context session] retain] autorelease];
182     [session lock];
183   }
184   
185   /* add session cookies to response */
186   [self addCookiesForSession:session
187         toResponse:response
188         inContext:context];
189     
190   /* store session if one was active */
191   [self saveSession:session
192         inContext:context
193         withResponse:response
194         application:app];
195   
196   return response;
197 }
198
199 @end /* WOPageRequestHandler */
200
201 @implementation WOComponent(DirectActionExtensions)
202
203 /* taking form values */
204
205 - (void)takeFormValuesForKeyArray:(NSArray *)_keys {
206   NSEnumerator *keys;
207   NSString     *key;
208   WORequest    *rq;
209
210   rq   = [[self context] request];
211   keys = [_keys objectEnumerator];
212
213   while ((key = [keys nextObject]))
214     [self takeValue:[rq formValueForKey:key] forKey:key];
215 }
216 - (void)takeFormValuesForKeys:(NSString *)_key1,... {
217   va_list   va;
218   NSString  *key;
219   WORequest *rq;
220   
221   rq = [[self context] request];
222   va_start(va, _key1);
223   for (key = _key1; key != nil; key = va_arg(va, NSString *))
224     [self takeValue:[rq formValueForKey:key] forKey:key];
225   va_end(va);
226 }
227
228 /* perform actions */
229
230 - (id<WOActionResults>)defaultAction {
231   return self;
232 }
233
234 - (id<WOActionResults>)performActionNamed:(NSString *)_actionName {
235   SEL actionSel;
236   NSRange rng;
237   
238   /* discard everything after a point in the URL */
239   rng = [_actionName rangeOfString:@"."];
240   if (rng.length > 0)
241     _actionName = [_actionName substringToIndex:rng.location];
242   
243   _actionName = [_actionName stringByAppendingString:@"Action"];
244   
245   if ((actionSel = NSSelectorFromString(_actionName)) == NULL) {
246     [self debugWithFormat:@"did not find selector for action: %@", 
247             _actionName];
248     return [self defaultAction];
249   }
250   
251   if ([self respondsToSelector:actionSel]) 
252     return [self performSelector:actionSel];
253
254   if (debugUnknownActions) {
255     [self logWithFormat:@"Page class %@ cannot handle action %@",
256             NSStringFromClass([self class]), _actionName];
257   }
258   return [self defaultAction];
259 }
260
261 @end /* WOComponent(DirectActionExtensions) */