2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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
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.
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
22 #include <NGObjWeb/WODynamicElement.h>
24 @interface WOConditional : WODynamicElement
27 // WODynamicElement: extraAttributes
28 // WODynamicElement: otherTagString
30 WOAssociation *condition;
31 WOAssociation *negate;
35 WOAssociation *value; // compare the condition with value
42 @end /* WOConditional */
45 #include <NGObjWeb/WOxElemBuilder.h>
47 #include "WOElement+private.h"
49 // TODO: make that a class cluster for improved performance
51 @implementation WOConditional
53 static int descriptiveIDs = -1;
56 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
58 descriptiveIDs = [ud boolForKey:@"WODescriptiveElementIDs"] ? 1 : 0;
61 - (id)initWithName:(NSString *)_name
62 associations:(NSDictionary *)_config
63 template:(WOElement *)_c
66 self->condName = _name ? [_name copy] : @"condYES";
69 if ((self = [super initWithName:_name associations:_config template:_c])) {
70 self->condition = OWGetProperty(_config, @"condition");
71 self->negate = OWGetProperty(_config, @"negate");
72 self->value = OWGetProperty(_config, @"value");
73 self->template = [_c retain];
75 if (self->condition == nil) {
77 @"WARNING: missing 'condition' association in element: '%@'",
84 - (id)initWithNegateElement:(id<DOMElement>)_element
85 templateBuilder:(WOxElemBuilder *)_builder
87 /* need an own -init so that we can patch the 'negate' association */
89 NSMutableDictionary *assocs;
91 id<NSObject,DOMNamedNodeMap> attrs;
94 name = [_element tagName];
96 /* construct associations */
99 attrs = [_element attributes];
100 if ((count = [attrs length]) > 0)
101 assocs = [_builder associationsForAttributes:attrs];
103 if ([assocs objectForKey:@"negate"] != nil) {
105 [self logWithFormat:@"TODO: if-not with 'negate' binding not supported!"];
110 static WOAssociation *yesAssoc = nil;
111 if (yesAssoc == nil) {
112 yesAssoc = [[WOAssociation associationWithValue:
113 [NSNumber numberWithBool:YES]] retain];
115 [assocs setObject:yesAssoc forKey:@"negate"];
118 /* construct child elements */
120 if ([_element hasChildNodes]) {
121 /* look for var:binding tags ... */
123 children = [_builder buildNodes:[_element childNodes]
124 templateBuilder:_builder];
129 /* construct self ... */
130 return [self initWithName:name associations:assocs contentElements:children];
133 - (id)initWithElement:(id<DOMElement>)_element
134 templateBuilder:(WOxElemBuilder *)_builder
138 tag = [_element tagName];
139 if ([tag isEqualToString:@"if-not"] || [tag isEqualToString:@"ifnot"])
140 return [self initWithNegateElement:_element templateBuilder:_builder];
142 return [super initWithElement:_element templateBuilder:_builder];
146 [self->template release];
147 [self->value release];
148 [self->condition release];
149 [self->negate release];
151 [self->condName release];
158 - (WOElement *)template {
159 return self->template;
164 static inline BOOL _doShow(WOConditional *self, WOContext *_ctx) {
165 WOComponent *cmp = [_ctx component];
167 BOOL doNegate = [self->negate boolValueInComponent:cmp];
170 id v = [self->value valueInComponent:cmp];
171 id cv = [self->condition valueInComponent:cmp];
173 doShow = [cv isEqual:v];
176 doShow = [self->condition boolValueInComponent:cmp];
178 return doNegate ? !doShow : doShow;
181 /* processing requests */
183 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
184 if (!_doShow(self, _ctx)) {
186 NSLog(@"didn't take value from request: %@\n doShow=%@\n doNegate=%@",
188 self->condition, self->negate);
194 [_ctx appendElementIDComponent:descriptiveIDs ? self->condName : @"1"];
196 [_ctx appendElementIDComponent:@"1"];
198 [self->template takeValuesFromRequest:_rq inContext:_ctx];
199 [_ctx deleteLastElementIDComponent];
202 - (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
207 state = [[_ctx currentElementID] stringValue];
212 [_ctx consumeElementID]; // consume state-id (on or off)
215 key = descriptiveIDs ? self->condName : @"1";
220 if (![state isEqualToString:key])
223 [_ctx appendElementIDComponent:state];
224 result = [self->template invokeActionForRequest:_rq inContext:_ctx];
225 [_ctx deleteLastElementIDComponent];
229 /* generating response */
231 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
232 if (!_doShow(self, _ctx))
235 [_ctx appendElementIDComponent:descriptiveIDs ? self->condName : @"1"];
237 [_ctx appendElementIDComponent:@"1"];
240 [self->template appendToResponse:_response inContext:_ctx];
241 [_ctx deleteLastElementIDComponent];
246 - (NSString *)associationDescription {
247 NSMutableString *str;
249 str = [NSMutableString stringWithCapacity:64];
250 if (self->condition) [str appendFormat:@" condition=%@", self->condition];
251 if (self->negate) [str appendFormat:@" negate=%@", self->negate];
252 if (self->template) [str appendFormat:@" template=%@", self->template];
256 @end /* WOConditional */