Guest User

Untitled

a guest
Jan 29th, 2026
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.32 KB | None | 0 0
  1. /* perform dispatch */
  2.  
  3. - (id)dispatchInContext:(WOContext *)_ctx {
  4. NSAutoreleasePool *pool;
  5. WORequest *rq;
  6. NSString *httpMethod;
  7. id clientObject;
  8. id methodObject;
  9. id resultObject;
  10.  
  11. if (debugOn) {
  12. [self debugWithFormat:@"dispatchInContext: START"];
  13. [self debugWithFormat:@" context = %@", _ctx];
  14. }
  15.  
  16. pool = [[NSAutoreleasePool alloc] init];
  17. rq = [_ctx request];
  18.  
  19. if (debugOn) {
  20. [self debugWithFormat:@" request = %@", rq];
  21. [self debugWithFormat:@" request method = %@", [rq method]];
  22. }
  23.  
  24. /* find client object */
  25.  
  26. if ((clientObject = [_ctx clientObject]) != nil) {
  27. if (debugOn)
  28. [self debugWithFormat:@"client object set in ctx: %@", clientObject];
  29. }
  30. else if ((clientObject = [self->object clientObject]) != nil) {
  31. if (debugOn)
  32. [self debugWithFormat:@"setting client object: %@", clientObject];
  33. [_ctx setClientObject:clientObject];
  34. }
  35. else if (debugOn) {
  36. [self debugWithFormat:@"no client object found"];
  37. }
  38.  
  39. /* check whether client object is a response ... */
  40.  
  41. if ([clientObject isKindOfClass:[WOResponse class]]) {
  42. [self debugWithFormat:@"clientObject is a WOResponse, returning that: %@",
  43. clientObject];
  44. resultObject = [clientObject retain];
  45. [pool release];
  46. return [resultObject autorelease];
  47. }
  48.  
  49. /*
  50. This X- field is used by Google which uses POST to trigger REST methods,
  51. don't ask me why ... ;-/
  52. */
  53.  
  54. if (![(httpMethod = [rq headerForKey:@"x-http-method-override"]) isNotEmpty]) {
  55. httpMethod = [rq method];
  56. if (debugOn)
  57. [self debugWithFormat:@"using HTTP method from request: %@", httpMethod];
  58. }
  59. else if (debugOn) {
  60. [self debugWithFormat:@"using overridden HTTP method: %@", httpMethod];
  61. }
  62.  
  63. /* find callable (method) object */
  64.  
  65. if ([self->object isCallable]) {
  66. if (debugOn)
  67. [self debugWithFormat:@"traversed object is callable: %@", self->object];
  68. methodObject = self->object;
  69. }
  70. else if ([[self->object soClass] hasKey:httpMethod inContext:_ctx]) {
  71. if (debugOn)
  72. [self debugWithFormat:
  73. @"class has method for HTTP verb '%@', looking it up", httpMethod];
  74.  
  75. methodObject = [self->object lookupName:[rq method]
  76. inContext:_ctx
  77. acquire:NO];
  78.  
  79. if (debugOn)
  80. [self debugWithFormat:@"lookup returned methodObject: %@", methodObject];
  81. }
  82. else if (useRedirectsForDefaultMethods) {
  83. NSString *defaultName;
  84.  
  85. if (debugOn)
  86. [self debugWithFormat:@"checking redirect to default method"];
  87.  
  88. methodObject = nil;
  89. defaultName = [self->object defaultMethodNameInContext:_ctx];
  90.  
  91. if ([defaultName isNotEmpty]) {
  92. WOResponse *r;
  93. NSString *url;
  94.  
  95. url = [self->object baseURLInContext:_ctx];
  96. if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"];
  97. url = [url stringByAppendingString:defaultName];
  98.  
  99. [self debugWithFormat:@"redirect to default method %@ of %@: %@",
  100. defaultName, self->object, url];
  101.  
  102. r = [[_ctx response] retain];
  103. [r setStatus:302 /* moved */];
  104. [r setHeader:url forKey:@"location"];
  105. [pool release];
  106. return [r autorelease];
  107. }
  108. else if (debugOn) {
  109. [self debugWithFormat:@"no default method name for redirect"];
  110. }
  111. }
  112. else {
  113. methodObject = [self->object lookupDefaultMethod];
  114. if (debugOn)
  115. [self debugWithFormat:@"using default method: %@", methodObject];
  116. }
  117.  
  118. /* apply arguments */
  119.  
  120. if ([methodObject respondsToSelector:
  121. @selector(takeValuesFromRequest:inContext:)]) {
  122. if (debugOn)
  123. [self debugWithFormat:@"applying values from request to %@",
  124. methodObject];
  125. [methodObject takeValuesFromRequest:rq inContext:_ctx];
  126. }
  127. else if (debugOn && methodObject != nil) {
  128. [self debugWithFormat:
  129. @"methodObject does not take request values: %@", methodObject];
  130. }
  131.  
  132. /* perform call */
  133.  
  134. if (methodObject == nil || ![methodObject isCallable]) {
  135. resultObject = self->object;
  136.  
  137. if (debugOn) {
  138. if (methodObject == nil) {
  139. [self debugWithFormat:
  140. @"no methodObject, using object as result: %@", resultObject];
  141. }
  142. else {
  143. [self debugWithFormat:
  144. @"methodObject not callable %@, using object as result: %@",
  145. methodObject, resultObject];
  146. }
  147. }
  148. }
  149. else {
  150. if (debugOn)
  151. [self debugWithFormat:@"calling %@ on client %@",
  152. methodObject, [_ctx clientObject]];
  153.  
  154. resultObject = [methodObject callOnObject:[_ctx clientObject]
  155. inContext:_ctx];
  156.  
  157. if (debugOn) {
  158. if ([resultObject isKindOfClass:[WOResponse class]]) {
  159. [self debugWithFormat:
  160. @"call produced response: 0x%p (code=%i)",
  161. resultObject, [(WOResponse *)resultObject status]];
  162. }
  163. else {
  164. [self debugWithFormat:
  165. @"call produced result: %@", resultObject];
  166. }
  167. }
  168. }
  169.  
  170. resultObject = [resultObject retain];
  171. [pool release];
  172.  
  173. if (debugOn)
  174. [self debugWithFormat:@"dispatchInContext: END -> %@", resultObject];
  175.  
  176. /* deliver result */
  177. return [resultObject autorelease];
  178. }
  179.  
  180. /* page construction */
  181.  
  182. - (id)instantiateMethodInContext:(id)_ctx {
  183. // Careful: this must return a RETAINED object!
  184. Class clazz;
  185. id lMethod;
  186.  
  187. if (debugOn){
  188. [self debugWithFormat:@"instantiateMethodInContext: START"];
  189. [self debugWithFormat:@" methodObject = %@", self->methodObject];
  190. [self debugWithFormat:@" context = %@", _ctx];
  191. }
  192.  
  193. if (_ctx == nil) {
  194. [self debugWithFormat:
  195. @"Note: got no explicit context for method instantiation, using application context."];
  196. _ctx = [[WOApplication application] context];
  197. if (debugOn) {
  198. [self debugWithFormat:@" resolved context = %@", _ctx];
  199. }
  200. }
  201.  
  202. /* find class */
  203.  
  204. if (debugOn) {
  205. [self debugWithFormat:@"Resolving action class name: %@",
  206. [self actionClassName]];
  207. }
  208.  
  209. if ((clazz = NSClassFromString([self actionClassName])) == Nil) {
  210. [self errorWithFormat:@"did not find action class: %@",
  211. [self actionClassName]];
  212. return nil;
  213. }
  214.  
  215. if (debugOn) {
  216. [self debugWithFormat:@"Resolved action class: %@", clazz];
  217. }
  218.  
  219. /* instantiate */
  220.  
  221. if ([clazz instancesRespondToSelector:@selector(initWithContext:)]) {
  222.  
  223. if (debugOn) {
  224. [self debugWithFormat:
  225. @"Instantiating using -initWithContext:"];
  226. }
  227.  
  228. lMethod = [[clazz alloc] initWithContext:_ctx];
  229. }
  230. else if ([clazz instancesRespondToSelector:@selector(initWithRequest:)]) {
  231.  
  232. if (debugOn) {
  233. [self debugWithFormat:
  234. @"Instantiating using -initWithRequest:"];
  235. [self debugWithFormat:
  236. @" request = %@",
  237. [(id<WOPageGenerationContext>)_ctx request]];
  238. }
  239.  
  240. lMethod = [[clazz alloc] initWithRequest:
  241. [(id<WOPageGenerationContext>)_ctx request]];
  242. }
  243. else {
  244.  
  245. if (debugOn) {
  246. [self debugWithFormat:
  247. @"Instantiating using plain -init"];
  248. }
  249.  
  250. lMethod = [[clazz alloc] init];
  251. }
  252.  
  253. if (debugOn) {
  254. [self debugWithFormat:@"Instantiation result: %@", lMethod];
  255. [self debugWithFormat:@"instantiateMethodInContext: END"];
  256. }
  257.  
  258. return lMethod;
  259. }
  260.  
Advertisement
Add Comment
Please, Sign In to add comment