2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include <NGObjWeb/WOActionURL.h>
23 #include "WOElement+private.h"
24 #include <NGObjWeb/WOApplication.h>
25 #include <NGObjWeb/WOResourceManager.h>
28 @interface _WOActionActionURL : WOActionURL
30 WOAssociation *action;
34 @interface _WOPageActionURL : WOActionURL
36 WOAssociation *pageName;
40 @interface _WODirectActionActionURL : WOActionURL
42 WOAssociation *actionClass;
43 WOAssociation *directActionName;
44 BOOL sidInUrl; /* include session-id in wa URL ? */
48 @interface WOActionURL(PrivateMethods)
50 - (id)_initWithName:(NSString *)_name
51 associations:(NSDictionary *)_config
52 template:(WOElement *)_t;
54 - (NSString *)associationDescription;
58 @implementation WOActionURL
64 NSAssert2([super version] == 2,
65 @"invalid superclass (%@) version %i !",
66 NSStringFromClass([self superclass]), [super version]);
69 + (BOOL)containsLinkInAssociations:(NSDictionary *)_assocs {
70 if (_assocs == nil) return NO;
71 if ([_assocs objectForKey:@"href"]) return YES;
72 if ([_assocs objectForKey:@"directActionName"]) return YES;
73 if ([_assocs objectForKey:@"pageName"]) return YES;
74 if ([_assocs objectForKey:@"action"]) return YES;
75 if ([_assocs objectForKey:@"actionClass"]) return YES;
79 - (id)initWithName:(NSString *)_name
80 associations:(NSDictionary *)_config
81 template:(WOElement *)_t
83 Class linkClass = Nil;
85 if ([_config objectForKey:@"action"])
86 linkClass = [_WOActionActionURL class];
87 else if ([_config objectForKey:@"pageName"])
88 linkClass = [_WOPageActionURL class];
90 linkClass = [_WODirectActionActionURL class];
94 [[linkClass alloc] initWithName:_name associations:_config template:_t];
97 - (id)_initWithName:(NSString *)_name
98 associations:(NSDictionary *)_config
99 template:(WOElement *)_t
101 if ((self = [super initWithName:_name associations:_config template:_t])) {
102 self->fragmentIdentifier = OWGetProperty(_config, @"fragmentIdentifier");
103 self->queryDictionary = OWGetProperty(_config, @"queryDictionary");
104 self->queryParameters = OWExtractQueryParameters(_config);
105 self->template = [_t retain];
106 self->containsForm = self->queryParameters ? YES : NO;
112 [self->template release];
113 [self->queryDictionary release];
114 [self->queryParameters release];
115 [self->fragmentIdentifier release];
122 return self->template;
125 /* handling requests */
127 - (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
128 /* links can take form values !!!! (for query-parameters) */
130 if (self->queryParameters) {
131 /* apply values to ?style parameters */
132 WOComponent *sComponent = [_ctx component];
136 keys = [self->queryParameters keyEnumerator];
137 while ((key = [keys nextObject])) {
140 assoc = [self->queryParameters objectForKey:key];
141 value = [_req formValueForKey:key];
143 [assoc setValue:value inComponent:sComponent];
147 [self->template takeValuesFromRequest:_req inContext:_ctx];
150 - (id)invokeActionForRequest:(WORequest *)_request
151 inContext:(WOContext *)_ctx
153 [[_ctx session] logWithFormat:@"%@[0x%p]: no action/page set !",
154 NSStringFromClass([self class]), self];
158 - (BOOL)_appendHrefToResponse:(WOResponse *)_r inContext:(WOContext *)_ctx {
159 #if APPLE_FOUNDATION_LIBRARY || NeXT_Foundation_LIBRARY || \
160 COCOA_Foundation_LIBRARY
161 NSLog(@"subclass responsibility ...");
163 [self subclassResponsibility:_cmd];
168 /* generate response */
170 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
171 WOComponent *sComponent;
172 NSString *queryString = nil;
174 if ([_ctx isRenderingDisabled] || [[_ctx request] isFromClientComponent]) {
175 [self->template appendToResponse:_response inContext:_ctx];
179 sComponent = [_ctx component];
181 if ([self _appendHrefToResponse:_response inContext:_ctx]) {
182 queryString = [self queryStringForQueryDictionary:
183 [self->queryDictionary valueInComponent:sComponent]
184 andQueryParameters:self->queryParameters
188 if (self->fragmentIdentifier != nil) {
189 [_response appendContentCharacter:'#'];
190 WOResponse_AddString(_response,
191 [self->fragmentIdentifier stringValueInComponent:sComponent]);
193 if (queryString != nil) {
194 [_response appendContentCharacter:'?'];
195 WOResponse_AddString(_response, queryString);
199 [self->template appendToResponse:_response inContext:_ctx];
204 - (NSString *)associationDescription {
205 NSMutableString *str = [NSMutableString stringWithCapacity:256];
207 if (self->fragmentIdentifier)
208 [str appendFormat:@" fragment=%@", self->fragmentIdentifier];
213 @end /* WOActionURL */
215 @implementation _WOActionActionURL
217 - (id)initWithName:(NSString *)_name
218 associations:(NSDictionary *)_config
219 template:(WOElement *)_t
221 if ((self = [super _initWithName:_name associations:_config template:_t])) {
222 self->action = OWGetProperty(_config, @"action");
224 if (self->action == nil) {
225 NSLog(@"missing action association for WOActionURL ..");
231 if ([_config objectForKey:@"pageName"] ||
232 [_config objectForKey:@"href"] ||
233 [_config objectForKey:@"directActionName"] ||
234 [_config objectForKey:@"actionClass"]) {
235 NSLog(@"WARNING: inconsistent association settings in WOActionURL !"
236 @" (assign only one of pageName, href, "
237 @"directActionName or action)");
245 [self->action release];
249 /* dynamic invocation */
251 - (id)invokeActionForRequest:(WORequest *)_request
252 inContext:(WOContext *)_ctx
255 return [self executeAction:self->action inContext:_ctx];
258 - (BOOL)_appendHrefToResponse:(WOResponse *)_response
259 inContext:(WOContext *)_ctx
261 WOResponse_AddString(_response, [_ctx componentActionURL]);
267 - (NSString *)associationDescription {
268 NSMutableString *str = [NSMutableString stringWithCapacity:256];
270 [str appendFormat:@" action=%@", self->action];
271 [str appendString:[super associationDescription]];
275 @end /* _WOActionActionURL */
277 @implementation _WOPageActionURL
279 - (id)initWithName:(NSString *)_name
280 associations:(NSDictionary *)_config
281 template:(WOElement *)_t
283 if ((self = [super _initWithName:_name associations:_config template:_t])) {
284 self->pageName = OWGetProperty(_config, @"pageName");
286 if (self->pageName == nil) {
287 NSLog(@"missing pageName association for WOActionURL ..");
293 if ([_config objectForKey:@"action"] ||
294 [_config objectForKey:@"href"] ||
295 [_config objectForKey:@"directActionName"] ||
296 [_config objectForKey:@"actionClass"]) {
297 NSLog(@"WARNING: inconsistent association settings in WOActionURL !"
298 @" (assign only one of pageName, href, "
299 @"directActionName or action)");
307 [self->pageName release];
313 - (id)invokeActionForRequest:(WORequest *)_request
314 inContext:(WOContext *)_ctx
316 WOComponent *page = nil;
317 NSString *name = nil;
319 name = [self->pageName stringValueInComponent:[_ctx component]];
320 page = [[_ctx application] pageWithName:name inContext:_ctx];
323 [[_ctx session] logWithFormat:
324 @"%@[0x%p]: did not find page with name %@ !",
325 NSStringFromClass([self class]), self, name];
330 - (BOOL)_appendHrefToResponse:(WOResponse *)_response
331 inContext:(WOContext *)_ctx
333 WOResponse_AddString(_response, [_ctx componentActionURL]);
339 - (NSString *)associationDescription {
340 NSMutableString *str = [NSMutableString stringWithCapacity:256];
342 [str appendFormat:@" pageName=%@", self->pageName];
343 [str appendString:[super associationDescription]];
347 @end /* _WOPageActionURL */
349 @implementation _WODirectActionActionURL
351 - (id)initWithName:(NSString *)_name
352 associations:(NSDictionary *)_config
353 template:(WOElement *)_t
355 if ((self = [super _initWithName:_name associations:_config template:_t])) {
356 WOAssociation *sidInUrlAssoc;
358 sidInUrlAssoc = OWGetProperty(_config, @"?wosid");
359 self->actionClass = OWGetProperty(_config, @"actionClass");
360 self->directActionName = OWGetProperty(_config, @"directActionName");
362 self->sidInUrl = (sidInUrlAssoc)
363 ? [sidInUrlAssoc boolValueInComponent:nil]
367 if ([_config objectForKey:@"action"] ||
368 [_config objectForKey:@"href"] ||
369 [_config objectForKey:@"pageName"]) {
370 NSLog(@"WARNING: inconsistent association settings in WOActionURL !"
371 @" (assign only one of pageName, href, "
372 @"directActionName or action)");
380 [self->actionClass release];
381 [self->directActionName release];
387 - (BOOL)_appendHrefToResponse:(WOResponse *)_response
388 inContext:(WOContext *)_ctx
390 WOComponent *sComponent;
393 NSMutableDictionary *qd;
396 sComponent = [_ctx component];
397 daClass = [self->actionClass stringValueInComponent:sComponent];
398 daName = [self->directActionName stringValueInComponent:sComponent];
402 if (![daClass isEqualToString:@"DirectAction"])
403 daName = [NSString stringWithFormat:@"%@/%@", daClass, daName];
409 qd = [NSMutableDictionary dictionaryWithCapacity:16];
411 /* add query dictionary */
413 if (self->queryDictionary) {
414 if ((tmp = [self->queryDictionary valueInComponent:sComponent]))
415 [qd addEntriesFromDictionary:tmp];
418 /* add ?style parameters */
420 if (self->queryParameters) {
424 keys = [self->queryParameters keyEnumerator];
425 while ((key = [keys nextObject]) != nil) {
428 assoc = [self->queryParameters objectForKey:key];
429 value = [assoc stringValueInComponent:sComponent];
431 [qd setObject:(value != nil ? value : (id)@"") forKey:key];
437 if (self->sidInUrl) {
438 if ([_ctx hasSession]) {
439 WOSession *sn = [_ctx session];
441 [qd setObject:[sn sessionID] forKey:WORequestValueSessionID];
443 if (![sn isDistributionEnabled]) {
444 [qd setObject:[[WOApplication application] number]
445 forKey:WORequestValueInstance];
450 WOResponse_AddString(_response,
451 [_ctx directActionURLForActionNamed:daName
452 queryDictionary:qd]);
458 - (NSString *)associationDescription {
459 NSMutableString *str = [NSMutableString stringWithCapacity:256];
461 if (self->actionClass != nil)
462 [str appendFormat:@" actionClass=%@", self->actionClass];
463 if (self->directActionName != nil)
464 [str appendFormat:@" directAction=%@", self->directActionName];
466 [str appendString:[super associationDescription]];
470 @end /* _WODirectActionActionURL */