File: OWViewRequestHandler.m

package info (click to toggle)
sope 5.12.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,588 kB
  • sloc: objc: 169,223; sh: 3,823; ansic: 3,409; javascript: 446; python: 318; makefile: 185
file content (283 lines) | stat: -rw-r--r-- 8,020 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/*
  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 <NGObjWeb/OWViewRequestHandler.h>
#include "WORequestHandler+private.h"
#include "WOContext+private.h"
#include "WOComponent+private.h"
#include "WOApplication+private.h"
#include <NGObjWeb/WOComponent.h>
#include <NGObjWeb/WORequest.h>
#include <NGObjWeb/WOResponse.h>
#include <NGObjWeb/WOSessionStore.h>
#include <NGObjWeb/WOSession.h>
#include "common.h"

NSString *OWAppDidRefuseSessionName = @"OWAppDidRefuseSession";
static BOOL perflog = NO;

//#define USE_POOLS 1

#if USE_POOLS
#  warning extensive pools are enabled ...
#endif

@implementation OWViewRequestHandler

+ (void)initialize {
  perflog = [[NSUserDefaults standardUserDefaults]
                             boolForKey:@"OWViewRequestHandlerProfile"];
}

- (NSString *)loggingPrefix {
  return @"[ow-handler]";
}

- (id)init {
  //NSLog(@"DEPRECATED: OWViewRequestHandler is being allocated ...");
  return [super init];
}

- (WOResponse *)runTransactionWithContext:(WOContext *)_ctx {
  WOApplication *app      = nil;
  WOSession     *sn       = nil;
  WOResponse    *response = nil;
  id<NSObject,WOActionResults> result;
  
  app = [_ctx application];
  sn  = [_ctx session];
  NSAssert(_ctx != nil, @"no context available");
  NSAssert(sn   != nil, @"no session available");
  NSAssert(app  != nil, @"no application available in context");

  /* take request values */

  [app takeValuesFromRequest:[_ctx request] inContext:_ctx];

  /* invoke action */
    
  result = [app invokeActionForRequest:[_ctx request] inContext:_ctx];
    
  /* check whether there is an page set at all ! */

  if ([_ctx page] == nil) {
    /* no page is set yet, load Main .. */
    WOComponent *mainPage;

    if ((mainPage = [app pageWithName:nil inContext:_ctx])) {
      [_ctx setPage:mainPage];
      [mainPage _awakeWithContext:_ctx];
    }
  }
  
  /* make response */
  
  if ((result == nil) || [result isKindOfClass:[WOComponent class]]) {
    /* determine the response page */
      
    if (result == nil) {
      /* make the request page the response page */
      if ((result = [_ctx page]) == nil) {
        /* no request page (probably the first request) */
        result = [app pageWithName:nil inContext:_ctx];
        [(id)result _awakeWithContext:_ctx];
        [_ctx setPage:(WOComponent *)result];
      }
    }

    response = [self generateResponseForComponent:(WOComponent *)result
                     inContext:_ctx
                     application:app];
      
    /* save page in session */
      
    if ([_ctx savePageRequired]) {
      [sn savePage:[_ctx page]];
#if DEBUG && 0
      [self logWithFormat:@"saved page ..."];
#endif
    }
#if DEBUG && 0
    else {
      [self logWithFormat:@"no save page required ..."];
    }
#endif
  }
  else {
    /* generate response from WOActionResult */
    if ([result respondsToSelector:@selector(generateResponse)]) {
      [app debugWithFormat:@"generating response for result .."];
      response = [result generateResponse];
    }
    else {
      [app logWithFormat:
             @"action result (class=%@) doesn't conform to "
             @"WOActionResult protocol !",
             NSStringFromClass([result class])];
        
      response = [[WOResponse alloc] init];
      [response setStatus:200];
      [response appendContentString:@"<pre>"];
      [response appendContentHTMLString:
                  @"ERROR:\n"
                  @"Result of action doesn't conform to WOActionResult "
                  @"protocol:\n---\n"
                  @"Content-Class: "];
      [response appendContentHTMLString:
                   [NSStringFromClass([result class]) description]];
      [response appendContentHTMLString:@"\nContent:\n"];
      [response appendContentHTMLString:[result description]];
      [response appendContentString:@"</pre>\n"];
      AUTORELEASE(response);
    }
  }
    
  [_ctx sleepComponents];
    
  return response;
}

- (NSString *)sessionIDFromRequest:(WORequest *)_request
  application:(WOApplication *)_app
{
  NSString *sessionId = nil;
  id tmp;
  
  if ((tmp = [_request formValueForKey:WORequestValueSenderID]) == nil) {
    if ([[_request requestHandlerPath] length] > 0) {
      /* traditional style URLs */
      NSArray *spath;
      
      spath = [_request requestHandlerPathArray];
      if ([spath count] > 0)
        sessionId = [spath objectAtIndex:0];
    }
  }
  
  if ([sessionId length] == 0)
    sessionId = [_app sessionIDFromRequest:_request];
  
  return sessionId;
}

- (BOOL)autocreateSessionForRequest:(WORequest *)_request {
  /* autocreate a session if none was restored */
  return YES;
}
- (BOOL)requiresSessionForRequest:(WORequest *)_request {
  /* _ensure_ that a session is available */
  return YES;
}

- (WOResponse *)handleRequest:(WORequest *)_request
  inContext:(WOContext *)context
  session:(WOSession *)session
  application:(WOApplication *)app
{
  NSString       *requestContextID;
  WOResponse     *response;
  WOComponent    *requestComponent;
  NSString       *cid;
  NSTimeInterval startRunTx = 0.0;
  id tmp;

  *(&requestContextID) = nil;
  *(&response)         = nil;
  *(&requestComponent) = nil;
  
  NSAssert(session, @"no session given !");

  /*
    parse handler path (URL)
      
    The format is:
      session/context-id.element-id
      
    or
      pageName?_i=context-id.element-id&wosid=session&_c=context-id
  */
  
  if ((tmp = [_request formValueForKey:WORequestValueSenderID])) {
    /* new query-para style URL */
    [context setRequestSenderID:tmp];
    
    if ((tmp = [_request formValueForKey:WORequestValueContextID]))
      requestContextID = tmp;
    else
      requestContextID = [context currentElementID];
  }
  else if ([[_request requestHandlerPath] length] > 0) {
    /* traditional style URLs */
    NSArray *spath;
    
    spath = [_request requestHandlerPathArray];
      
    if ([spath count] > 1) {
      [context setRequestSenderID:[spath objectAtIndex:1]];
      requestContextID = [context currentElementID];
    }
    // at idx 0 => sessionId
  }
  
  /* determine request component */

  if ([[self sessionIDFromRequest:_request application:app]
             isEqualToString:[session sessionID]])
    cid = [context currentElementID];
  else
    /* the session is different, was autocreated ... */
    cid = nil;
  
  if ((session != nil) && ([cid length] > 0)) {
    requestComponent = [session restorePageForContextID:cid];
    
    if (requestComponent == nil) {
      /* could not restore page ... */
      response = [app handlePageRestorationErrorInContext:context];
      if (response != nil) {
        [self logWithFormat:
                @"returning because of page restoration error ..."];
        return response;
      }
    }
  }
  if (requestComponent) {
    [context setPage:requestComponent];
    [requestComponent _awakeWithContext:context];
  }
  
  /* run transaction */

  if (perflog)
    startRunTx = [[NSDate date] timeIntervalSince1970];
  
  response = [self runTransactionWithContext:context];
  
  if (perflog) {
    NSTimeInterval rt;
    rt = [[NSDate date] timeIntervalSince1970] - startRunTx;
    [self logWithFormat:@"running tx took %4.3fs.", rt < 0.0 ? -1.0 : rt];
  }
  
  return response;
}

@end /* OWViewRequestHandler */