]> err.no Git - sope/blob - sope-appserver/NGObjWeb/DynamicElements/WOActionURL.m
renamed packages as discussed in the developer list
[sope] / sope-appserver / NGObjWeb / DynamicElements / WOActionURL.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23 #include "WOHTMLDynamicElement.h"
24 #include "WOElement+private.h"
25 #include <NGObjWeb/WOApplication.h>
26 #include <NGObjWeb/WOResourceManager.h>
27 #include "common.h"
28
29 /*
30   WOActionURL associations:
31
32     pageName | action | (directActionName & actionClass)
33     fragmentIdentifier
34     queryDictionary
35 */
36
37 @interface WOActionURL : WOHTMLDynamicElement
38 {
39   // WODynamicElement: extraAttributes
40   // WODynamicElement: otherTagString
41 @protected
42   WOAssociation *fragmentIdentifier;
43   WOElement     *template;
44
45   /* new in WO4: */
46   WOAssociation *queryDictionary;
47   NSDictionary  *queryParameters;  /* associations beginning with ? */
48 }
49
50 @end /* WOActionURL */
51
52 @interface _WOActionActionURL : WOActionURL
53 {
54   WOAssociation *action;
55 }
56 @end
57
58 @interface _WOPageActionURL : WOActionURL
59 {
60   WOAssociation *pageName;
61 }
62 @end
63
64 @interface _WODirectActionActionURL : WOActionURL
65 {
66   WOAssociation *actionClass;
67   WOAssociation *directActionName;
68   BOOL          sidInUrl;          /* include session-id in wa URL ? */
69 }
70 @end
71
72 @interface WOActionURL(PrivateMethods)
73
74 - (id)_initWithName:(NSString *)_name
75   associations:(NSDictionary *)_config
76   template:(WOElement *)_t;
77
78 - (NSString *)associationDescription;
79
80 @end
81
82 @implementation WOActionURL
83
84 + (int)version {
85   return 1;
86 }
87 + (void)initialize {
88   NSAssert2([super version] == 2,
89             @"invalid superclass (%@) version %i !",
90             NSStringFromClass([self superclass]), [super version]);
91 }
92
93 - (id)initWithName:(NSString *)_name
94   associations:(NSDictionary *)_config
95   template:(WOElement *)_t
96 {
97   Class linkClass = Nil;
98   
99   if ([_config objectForKey:@"action"])
100     linkClass = [_WOActionActionURL class];
101   else if ([_config objectForKey:@"pageName"])
102     linkClass = [_WOPageActionURL class];
103   else
104     linkClass = [_WODirectActionActionURL class];
105
106   [self release];
107   return
108     [[linkClass alloc] initWithName:_name associations:_config template:_t];
109 }
110
111 - (id)_initWithName:(NSString *)_name
112   associations:(NSDictionary *)_config
113   template:(WOElement *)_t
114 {
115   if ((self = [super initWithName:_name associations:_config template:_t])) {
116     self->fragmentIdentifier = OWGetProperty(_config, @"fragmentIdentifier");
117     self->queryDictionary    = OWGetProperty(_config, @"queryDictionary");
118     self->queryParameters    = OWExtractQueryParameters(_config);
119     self->template           = [_t retain];
120     self->containsForm       = self->queryParameters ? YES : NO;
121   }
122   return self;
123 }
124
125 - (void)dealloc {
126   RELEASE(self->template);
127   RELEASE(self->queryDictionary);
128   RELEASE(self->queryParameters);
129   RELEASE(self->fragmentIdentifier);
130   [super dealloc];
131 }
132
133 /* accessors */
134
135 - (WOElement *)template {
136   return self->template;
137 }
138
139 // ******************** responder ********************
140
141 - (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
142   /* links can take form values !!!! (for query-parameters) */
143
144   if (self->queryParameters) {
145     /* apply values to ?style parameters */
146     WOComponent  *sComponent = [_ctx component];
147     NSEnumerator *keys;
148     NSString     *key;
149
150     keys = [self->queryParameters keyEnumerator];
151     while ((key = [keys nextObject])) {
152       id assoc, value;
153
154       assoc = [self->queryParameters objectForKey:key];
155       value = [_req formValueForKey:key];
156
157       [assoc setValue:value inComponent:sComponent];
158     }
159   }
160   
161   [self->template takeValuesFromRequest:_req inContext:_ctx];
162 }
163
164 - (id)invokeActionForRequest:(WORequest *)_request
165   inContext:(WOContext *)_ctx
166 {
167   [[_ctx session] logWithFormat:@"%@[0x%08X]: no action/page set !",
168                     NSStringFromClass([self class]), self];
169   return nil;
170 }
171
172 - (BOOL)_appendHrefToResponse:(WOResponse *)_r inContext:(WOContext *)_ctx {
173 #if APPLE_FOUNDATION_LIBRARY || NeXT_Foundation_LIBRARY || \
174     COCOA_Foundation_LIBRARY
175   NSLog(@"subclass responsibility ...");
176 #else
177   [self subclassResponsibility:_cmd];
178 #endif
179   return NO;
180 }
181
182 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
183   if (![[_ctx request] isFromClientComponent]) {
184     WOComponent *sComponent = [_ctx component];
185     NSString *queryString = nil;
186   
187     if ([self _appendHrefToResponse:_response inContext:_ctx]) {
188       queryString = [self queryStringForQueryDictionary:
189                             [self->queryDictionary valueInComponent:sComponent]
190                           andQueryParameters:self->queryParameters
191                           inContext:_ctx];
192     }
193   
194     if (self->fragmentIdentifier) {
195       [_response appendContentCharacter:'#'];
196       WOResponse_AddString(_response,
197          [self->fragmentIdentifier stringValueInComponent:sComponent]);
198     }
199     if (queryString) {
200       [_response appendContentCharacter:'?'];
201       WOResponse_AddString(_response, queryString);
202     }
203     
204     /* content */
205     [self->template appendToResponse:_response inContext:_ctx];
206   }
207 }
208
209 /* description */
210
211 - (NSString *)associationDescription {
212   NSMutableString *str = [NSMutableString stringWithCapacity:256];
213
214   if (self->fragmentIdentifier)
215     [str appendFormat:@" fragment=%@", self->fragmentIdentifier];
216
217   return str;
218 }
219
220 @end /* WOActionURL */
221
222 @implementation _WOActionActionURL
223
224 - (id)initWithName:(NSString *)_name
225   associations:(NSDictionary *)_config
226   template:(WOElement *)_t
227 {
228   if ((self = [super _initWithName:_name associations:_config template:_t])) {
229     self->action = OWGetProperty(_config, @"action");
230
231     if (self->action == nil) {
232       NSLog(@"missing action association for WOActionURL ..");
233       RELEASE(self);
234       return nil;
235     }
236
237 #if DEBUG
238     if ([_config objectForKey:@"pageName"] ||
239         [_config objectForKey:@"href"]     ||
240         [_config objectForKey:@"directActionName"] ||
241         [_config objectForKey:@"actionClass"]) {
242       NSLog(@"WARNING: inconsistent association settings in WOActionURL !"
243             @" (assign only one of pageName, href, "
244             @"directActionName or action)");
245     }
246 #endif
247   }
248   return self;
249 }
250
251 - (void)dealloc {
252   [self->action release];
253   [super dealloc];
254 }
255
256 /* dynamic invocation */
257
258 - (id)invokeActionForRequest:(WORequest *)_request
259   inContext:(WOContext *)_ctx
260 {
261   /* link is active */
262   return [self executeAction:self->action inContext:_ctx];
263 }
264
265 - (BOOL)_appendHrefToResponse:(WOResponse *)_response
266   inContext:(WOContext *)_ctx
267 {
268   WOResponse_AddString(_response, [_ctx componentActionURL]);
269   return YES;
270 }
271
272 /* description */
273
274 - (NSString *)associationDescription {
275   NSMutableString *str = [NSMutableString stringWithCapacity:256];
276
277   [str appendFormat:@" action=%@", self->action];
278   [str appendString:[super associationDescription]];
279   return str;
280 }
281
282 @end /* _WOActionActionURL */
283
284 @implementation _WOPageActionURL
285
286 - (id)initWithName:(NSString *)_name
287   associations:(NSDictionary *)_config
288   template:(WOElement *)_t
289 {
290   if ((self = [super _initWithName:_name associations:_config template:_t])) {
291     self->pageName = OWGetProperty(_config, @"pageName");
292
293     if (self->pageName == nil) {
294       NSLog(@"missing pageName association for WOActionURL ..");
295       RELEASE(self);
296       return nil;
297     }
298
299 #if DEBUG
300     if ([_config objectForKey:@"action"] ||
301         [_config objectForKey:@"href"]     ||
302         [_config objectForKey:@"directActionName"] ||
303         [_config objectForKey:@"actionClass"]) {
304       NSLog(@"WARNING: inconsistent association settings in WOActionURL !"
305             @" (assign only one of pageName, href, "
306             @"directActionName or action)");
307     }
308 #endif
309   }
310   return self;
311 }
312
313 - (void)dealloc {
314   [self->pageName release];
315   [super dealloc];
316 }
317
318 /* actions */
319
320 - (id)invokeActionForRequest:(WORequest *)_request
321   inContext:(WOContext *)_ctx
322 {
323   WOComponent *page = nil;
324   NSString    *name = nil;
325
326   name = [self->pageName stringValueInComponent:[_ctx component]];
327   page = [[_ctx application] pageWithName:name inContext:_ctx];
328
329   if (page == nil) {
330     [[_ctx session] logWithFormat:
331                       @"%@[0x%08X]: did not find page with name %@ !",
332                       NSStringFromClass([self class]), self, name];
333   }
334   return page;
335 }
336
337 - (BOOL)_appendHrefToResponse:(WOResponse *)_response
338   inContext:(WOContext *)_ctx
339 {
340   WOResponse_AddString(_response, [_ctx componentActionURL]);
341   return YES;
342 }
343
344 /* description */
345
346 - (NSString *)associationDescription {
347   NSMutableString *str = [NSMutableString stringWithCapacity:256];
348
349   [str appendFormat:@" pageName=%@", self->pageName];
350   [str appendString:[super associationDescription]];
351   return str;
352 }
353
354 @end /* _WOPageActionURL */
355
356 @implementation _WODirectActionActionURL
357
358 - (id)initWithName:(NSString *)_name
359   associations:(NSDictionary *)_config
360   template:(WOElement *)_t
361 {
362   if ((self = [super _initWithName:_name associations:_config template:_t])) {
363     WOAssociation *sidInUrlAssoc;
364     
365     sidInUrlAssoc          = OWGetProperty(_config, @"?wosid");
366     self->actionClass      = OWGetProperty(_config, @"actionClass");
367     self->directActionName = OWGetProperty(_config, @"directActionName");
368
369     self->sidInUrl = (sidInUrlAssoc)
370       ? [sidInUrlAssoc boolValueInComponent:nil]
371       : YES;
372     
373 #if DEBUG
374     if ([_config objectForKey:@"action"] ||
375         [_config objectForKey:@"href"]     ||
376         [_config objectForKey:@"pageName"]) {
377       NSLog(@"WARNING: inconsistent association settings in WOActionURL !"
378             @" (assign only one of pageName, href, "
379             @"directActionName or action)");
380     }
381 #endif
382   }
383   return self;
384 }
385
386 - (void)dealloc {
387   [self->actionClass      release];
388   [self->directActionName release];
389   [super dealloc];
390 }
391
392 /* href */
393
394 - (BOOL)_appendHrefToResponse:(WOResponse *)_response
395   inContext:(WOContext *)_ctx
396 {
397   WOComponent         *sComponent;
398   NSString            *daClass;
399   NSString            *daName;
400   NSMutableDictionary *qd;
401   NSDictionary        *tmp;
402
403   sComponent = [_ctx component];
404   daClass = [self->actionClass stringValueInComponent:sComponent];
405   daName  = [self->directActionName stringValueInComponent:sComponent];
406
407   if (daClass) {
408     if (daName) {
409       if (![daClass isEqualToString:@"DirectAction"])
410         daName = [NSString stringWithFormat:@"%@/%@", daClass, daName];
411     }
412     else
413       daName = daClass;
414   }
415
416   qd = [NSMutableDictionary dictionaryWithCapacity:16];
417
418       /* add query dictionary */
419       
420   if (self->queryDictionary) {
421     if ((tmp = [self->queryDictionary valueInComponent:sComponent]))
422       [qd addEntriesFromDictionary:tmp];
423   }
424       
425   /* add ?style parameters */
426
427   if (self->queryParameters) {
428     NSEnumerator *keys;
429     NSString     *key;
430
431     keys = [self->queryParameters keyEnumerator];
432     while ((key = [keys nextObject])) {
433       id assoc, value;
434
435       assoc = [self->queryParameters objectForKey:key];
436       value = [assoc stringValueInComponent:sComponent];
437           
438       [qd setObject:(value ? value : @"") forKey:key];
439     }
440   }
441       
442   /* add session ID */
443
444   if (self->sidInUrl) {
445     if ([_ctx hasSession]) {
446       WOSession *sn = [_ctx session];
447           
448       [qd setObject:[sn sessionID] forKey:WORequestValueSessionID];
449           
450       if (![sn isDistributionEnabled]) {
451         [qd setObject:[[WOApplication application] number]
452             forKey:WORequestValueInstance];
453       }
454     }
455   }
456
457   WOResponse_AddString(_response,
458                        [_ctx directActionURLForActionNamed:daName
459                              queryDictionary:qd]);
460   return NO;
461 }
462
463 /* description */
464
465 - (NSString *)associationDescription {
466   NSMutableString *str = [NSMutableString stringWithCapacity:256];
467
468   if (self->actionClass)
469     [str appendFormat:@" actionClass=%@", self->actionClass];
470   if (self->directActionName)
471     [str appendFormat:@" directAction=%@", self->directActionName];
472   
473   [str appendString:[super associationDescription]];
474   return str;
475 }
476
477 @end /* _WODirectActionActionURL */