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