/* Copyright (C) 2000-2005 SKYRIX Software AG This file is part of SOPE. SOPE is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. SOPE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with SOPE; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "WOComponentRequestHandler.h" #include "WORequestHandler+private.h" #include "WOContext+private.h" #include #include #include #include #include #include "common.h" @interface WOApplication(Privates) - (WOSession *)_initializeSessionInContext:(WOContext *)_ctx; - (void)_setCurrentContext:(WOContext *)_ctx; @end @implementation WOComponentRequestHandler + (int)version { return [super version] + 0 /* 2 */; } + (void)initialize { NSAssert2([super version] == 2, @"invalid superclass (%@) version %i !", NSStringFromClass([self superclass]), [super version]); } - (WOResponse *)restoreSessionWithID:(NSString *)_sid inContext:(WOContext *)_ctx { WOApplication *app = [WOApplication application]; WOResponse *response = nil; if (_sid == nil) { // invalid session ID (or no session-ID ?!, which is no error ?) */ response = [app handleSessionRestorationErrorInContext:_ctx]; } else { WOSession *session = nil; if ((session = [app restoreSessionWithID:_sid inContext:_ctx])) { // awake restored session [_ctx setSession:session]; [session _awakeWithContext:_ctx]; [session awake]; response = nil; } else { response = [app handleSessionRestorationErrorInContext:_ctx]; } } return response; } /* The request handler path of a component URI looks like this: sessionID/componentName/contextID/elementID/instance/server */ - (WOResponse *)handleRequest:(WORequest *)_request { NSString *sessionID = nil; WOApplication *application = nil; WOContext *context = nil; WOResponse *response = nil; WOSession *session = nil; WOComponent *component = nil; BOOL isLocked = NO; NSString *handlerPath = nil; if (_request == nil) return nil; application = [WOApplication application]; handlerPath = [_request requestHandlerPath]; #if 0 NSLog(@"[component request handler] path=%@ ..", handlerPath); #endif if (![application allowsConcurrentRequestHandling]) { [application lockRequestHandling]; isLocked = YES; } context = [WOContext contextWithRequest:_request]; [application _setCurrentContext:context]; /* parse handler path (URL) The format is: session/context.element-id */ if ([handlerPath length] > 0) { NSArray *spath = [_request requestHandlerPathArray]; if ([spath count] > 1) [context setRequestSenderID:[spath objectAtIndex:1]]; if ([spath count] > 0) sessionID = [spath objectAtIndex:0]; } if ([sessionID length] == 0) sessionID = [application sessionIDFromRequest:_request]; #if 0 NSLog(@"%s: made context %@ (cid=%@, sn=%@) ..", __PRETTY_FUNCTION__ context, [context contextID], sessionID); #endif [application awake]; /* restore or create session */ if (sessionID) { response = [self restoreSessionWithID:sessionID inContext:context]; session = response ? nil : [context session]; if (session) { /* awake stored page */ component = [session restorePageForContextID:[context currentElementID]]; if (component == nil) response = [application handlePageRestorationErrorInContext:context]; #if DEBUG else { NSLog(@"%s: restored request component %@", __PRETTY_FUNCTION__, component); } #endif } else if (response == nil) { [[WOApplication application] logWithFormat: @"WARNING: got no session restoration error, " @"but missing session !"]; } } else { /* create new session */ session = [application _initializeSessionInContext:context]; if (session) { /* awake created session */ [session awake]; component = [application pageWithName:nil inContext:context]; } else response = [application handleSessionCreationErrorInContext:context]; } if ((session != nil) && (component != nil) && (response == nil)) { WOComponent *newPage = nil; [[session retain] autorelease]; #if DEBUG NSAssert(application, @"missing application object .."); NSAssert(session, @"missing session object .."); #endif /* set request page in context */ [context setPage:component]; /* run take-values phase */ [application takeValuesFromRequest:_request inContext:context]; /* run invoke-action phase */ newPage = [application invokeActionForRequest:_request inContext:context]; /* process resulting page */ if (newPage == nil) { if ((newPage = [context page]) == nil) { newPage = [application pageWithName:nil inContext:context]; [context setPage:newPage]; } } else if ([newPage isKindOfClass:[WOComponent class]]) [context setPage:newPage]; #if DEBUG [self debugWithFormat:@"%s: new page: %@", __PRETTY_FUNCTION__, newPage]; #endif /* generate response */ #if 1 /* new code, ensure that _fixupResponse is called */ response = [self generateResponseForComponent:[context page] inContext:context application:application]; #else /* old code */ response = [context response]; [application appendToResponse:response inContext:context]; #endif } else { NSLog(@"WARNING(%s): did not enter request/response transaction ...", __PRETTY_FUNCTION__); } /* tear down */ /* sleep objects */ [context sleepComponents]; [session sleep]; /* save objects */ if (session) { if ([context savePageRequired]) [session savePage:[context page]]; NSLog(@"saving session %@", [session sessionID]); [application saveSessionForContext:context]; } [application sleep]; /* locking */ if (isLocked) { [application unlockRequestHandling]; isLocked = NO; } [application _setCurrentContext:nil]; return response; } @end /* WOComponentRequestHandler */