]> err.no Git - sope/blob - sope-appserver/WEExtensions/WEQualifierConditional.m
fixed copyrights for 2005
[sope] / sope-appserver / WEExtensions / WEQualifierConditional.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 /*
23   WEQualifierConditional
24
25     IfPerson: WEQualifierConditional {
26       condition = "isPerson=YES AND isCategory like '*customer*'";
27       object    = currentPerson;
28       negate    = NO;
29       bindings  = nil; // optional qualifier bindings
30       requiresAllVariables = YES; // whether all bindings must be resolved
31     }
32   
33   If no object is given, the qualifier is evaluated against the component.
34 */
35
36 #include <NGObjWeb/WODynamicElement.h>
37
38 @class WOAssociation;
39
40 @interface WEQualifierConditional : WODynamicElement
41 {
42 @protected
43   WOAssociation *condition;
44   WOAssociation *object;
45   WOAssociation *negate;
46   WOElement     *template;
47   WOAssociation *bindings;
48   WOAssociation *requiresAllVariables;
49 }
50 @end
51
52 #include "common.h"
53
54 // TODO: add support for qualifier arguments?
55
56 @implementation WEQualifierConditional
57
58 - (id)initWithName:(NSString *)_name
59   associations:(NSDictionary *)_config
60   template:(WOElement *)_t
61 {
62   if ((self = [super initWithName:_name associations:_config template:_t])) {
63     self->condition = WOExtGetProperty(_config, @"condition");
64     self->object    = WOExtGetProperty(_config, @"object");
65     self->negate    = WOExtGetProperty(_config, @"negate");
66     self->bindings  = WOExtGetProperty(_config, @"bindings");
67     self->requiresAllVariables = 
68       WOExtGetProperty(_config, @"requiresAllVariables");
69     self->template  = [_t retain];
70     
71     if (self->condition == nil) {
72       [self logWithFormat:
73               @"WARNING: missing 'condition' association in element: '%@'",
74               _name];
75     }
76     else if ([self->condition isValueConstant]) {
77       /* optimization, replace constant associations with a parsed qualifier */
78       NSString *value;
79       
80       if ((value = [self->condition stringValueInComponent:nil])) {
81         EOQualifier   *q;
82         
83         q = [EOQualifier qualifierWithQualifierFormat:value];
84         if (q) {
85           WOAssociation *tmp;
86           
87           tmp = [[WOAssociation associationWithValue:q] retain];
88           [self->condition release];
89           self->condition = tmp;
90         }
91       }
92     }
93   }
94   return self;
95 }
96
97 - (void)dealloc {
98   [self->template  release];
99   [self->condition release];
100   [self->object    release];
101   [self->negate    release];
102   [self->bindings  release];
103   [self->requiresAllVariables release];
104   [super dealloc];
105 }
106
107 /* accessors */
108
109 - (WOElement *)template {
110   return self->template;
111 }
112
113 /* state */
114
115 - (BOOL)_doShowInContext:(WOContext *)_ctx {
116   WOComponent  *cmp;
117   NSDictionary *vars;
118   NSArray      *args;
119   id   qualifier, context;
120   BOOL doShow, doNegate, needAllVars;
121   
122   cmp         = [_ctx component];
123   doNegate    = self->negate ? [self->negate boolValueInComponent:cmp] : NO;
124   doShow      = NO;
125   vars        = [self->bindings valueInComponent:cmp];
126   args        = nil;
127   needAllVars = self->requiresAllVariables 
128     ? [self->requiresAllVariables boolValueInComponent:cmp]
129     : NO;
130   
131   /* determine qualifier */
132   
133   if ((qualifier = [self->condition valueInComponent:cmp])) {
134     if ([qualifier isKindOfClass:[NSString class]]) {
135       qualifier = [EOQualifier qualifierWithQualifierFormat:qualifier
136                                arguments:args];
137     }
138   }
139   
140   /* apply qualifier bindings */
141   
142   if (vars != nil && qualifier != nil) {
143     qualifier = [qualifier qualifierWithBindings:vars 
144                            requiresAllVariables:needAllVars];
145   }
146   
147   /* find context object */
148   
149   context = self->object
150     ? [self->object valueInComponent:cmp]
151     : cmp;
152   
153   /* evaluate */
154   
155   if (![qualifier respondsToSelector:@selector(evaluateWithObject:)]) {
156     [self logWithFormat:
157             @"ERROR: got a qualifier which does not respond to "
158             @"evaluateWithObject: %@", qualifier];
159     doShow = NO;
160   }
161   else
162     doShow = [qualifier evaluateWithObject:context];
163   
164   return doNegate ? !doShow : doShow;
165 }
166
167 /* processing requests */
168
169 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
170   if (![self _doShowInContext:_ctx])
171     return;
172
173   [_ctx appendElementIDComponent:@"1"];
174   [self->template takeValuesFromRequest:_rq inContext:_ctx];
175   [_ctx deleteLastElementIDComponent];
176 }
177
178 - (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
179   NSString *state;
180   id result;
181
182   state = [[_ctx currentElementID] stringValue];
183   
184   if (!state) 
185     return nil;
186   [_ctx consumeElementID]; // consume state-id (on or off)
187   
188   if (![state isEqualToString:@"1"])
189     return nil;
190   
191   [_ctx appendElementIDComponent:state];
192   result = [self->template invokeActionForRequest:_rq inContext:_ctx];
193   [_ctx deleteLastElementIDComponent];
194   return result;
195 }
196
197 /* generating response */
198
199 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
200   if (![self _doShowInContext:_ctx])
201     return;
202
203   [_ctx appendElementIDComponent:@"1"];
204   [self->template appendToResponse:_response inContext:_ctx];
205   [_ctx deleteLastElementIDComponent];
206 }
207
208 /* description */
209
210 - (NSString *)associationDescription {
211   NSMutableString *str;
212
213   str = [NSMutableString stringWithCapacity:64];
214   if (self->condition) [str appendFormat:@" condition=%@", self->condition];
215   if (self->object)    [str appendFormat:@" object=%@",    self->object];
216   if (self->negate)    [str appendFormat:@" negate=%@",    self->negate];
217   if (self->template)  [str appendFormat:@" template=%@",  self->template];
218   return str;
219 }
220
221 @end /* WEQualifierConditional */