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/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] : (id)@"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 @"missing 'condition' association in element: '%@'", _name];
83 - (id)initWithNegateElement:(id<DOMElement>)_element
84 templateBuilder:(WOxElemBuilder *)_builder
86 /* need an own -init so that we can patch the 'negate' association */
88 NSMutableDictionary *assocs;
90 id<NSObject,DOMNamedNodeMap> attrs;
93 name = [_element tagName];
95 /* construct associations */
98 attrs = [_element attributes];
99 if ((count = [attrs length]) > 0)
100 assocs = [_builder associationsForAttributes:attrs];
102 if ([assocs objectForKey:@"negate"] != nil) {
104 [self logWithFormat:@"TODO: if-not with 'negate' binding not supported!"];
109 static WOAssociation *yesAssoc = nil;
110 if (yesAssoc == nil) {
111 yesAssoc = [[WOAssociation associationWithValue:
112 [NSNumber numberWithBool:YES]] retain];
114 [assocs setObject:yesAssoc forKey:@"negate"];
117 /* construct child elements */
119 if ([_element hasChildNodes]) {
120 /* look for var:binding tags ... */
122 children = [_builder buildNodes:[_element childNodes]
123 templateBuilder:_builder];
128 /* construct self ... */
129 return [self initWithName:name associations:assocs contentElements:children];
132 - (id)initWithElement:(id<DOMElement>)_element
133 templateBuilder:(WOxElemBuilder *)_builder
137 tag = [_element tagName];
138 if ([tag isEqualToString:@"if-not"] || [tag isEqualToString:@"ifnot"])
139 return [self initWithNegateElement:_element templateBuilder:_builder];
141 return [super initWithElement:_element templateBuilder:_builder];
145 [self->template release];
146 [self->value release];
147 [self->condition release];
148 [self->negate release];
150 [self->condName release];
158 return self->template;
163 static inline BOOL _doShow(WOConditional *self, WOContext *_ctx) {
164 WOComponent *cmp = [_ctx component];
166 BOOL doNegate = [self->negate boolValueInComponent:cmp];
169 id v = [self->value valueInComponent:cmp];
170 id cv = [self->condition valueInComponent:cmp];
172 doShow = [cv isEqual:v];
175 doShow = [self->condition boolValueInComponent:cmp];
177 return doNegate ? !doShow : doShow;
180 /* processing requests */
182 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
183 if (!_doShow(self, _ctx)) {
185 NSLog(@"didn't take value from request: %@\n doShow=%@\n doNegate=%@",
187 self->condition, self->negate);
193 [_ctx appendElementIDComponent:
194 descriptiveIDs ? self->condName : (NSString *)@"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 : (NSString *)@"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:
236 descriptiveIDs ? self->condName : (NSString *)@"1"];
238 [_ctx appendElementIDComponent:@"1"];
241 [self->template appendToResponse:_response inContext:_ctx];
242 [_ctx deleteLastElementIDComponent];
247 - (NSString *)associationDescription {
248 NSMutableString *str;
250 str = [NSMutableString stringWithCapacity:64];
251 if (self->condition) [str appendFormat:@" condition=%@", self->condition];
252 if (self->negate) [str appendFormat:@" negate=%@", self->negate];
253 if (self->template) [str appendFormat:@" template=%@", self->template];
257 @end /* WOConditional */