]> err.no Git - sope/blob - sope-appserver/WEExtensions/WEQualifierConditional.m
Add libxml2-dev to libsope-xml4.7-dev deps
[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 - (id)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 != nil)
150     ? [self->object valueInComponent:cmp]
151     : (id)cmp;
152   
153   /* evaluate */
154   
155   if (![qualifier respondsToSelector:@selector(evaluateWithObject:)]) {
156     [self errorWithFormat:@"got a qualifier which does not respond to "
157                           @"evaluateWithObject: %@", qualifier];
158     doShow = NO;
159   }
160   else
161     doShow = [qualifier evaluateWithObject:context];
162   
163   return doNegate ? !doShow : doShow;
164 }
165
166 /* processing requests */
167
168 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
169   if (![self _doShowInContext:_ctx])
170     return;
171
172   [_ctx appendElementIDComponent:@"1"];
173   [self->template takeValuesFromRequest:_rq inContext:_ctx];
174   [_ctx deleteLastElementIDComponent];
175 }
176
177 - (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
178   NSString *state;
179   id result;
180
181   state = [[_ctx currentElementID] stringValue];
182   
183   if (!state) 
184     return nil;
185   [_ctx consumeElementID]; // consume state-id (on or off)
186   
187   if (![state isEqualToString:@"1"])
188     return nil;
189   
190   [_ctx appendElementIDComponent:state];
191   result = [self->template invokeActionForRequest:_rq inContext:_ctx];
192   [_ctx deleteLastElementIDComponent];
193   return result;
194 }
195
196 /* generating response */
197
198 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
199   if (![self _doShowInContext:_ctx])
200     return;
201
202   [_ctx appendElementIDComponent:@"1"];
203   [self->template appendToResponse:_response inContext:_ctx];
204   [_ctx deleteLastElementIDComponent];
205 }
206
207 /* description */
208
209 - (NSString *)associationDescription {
210   NSMutableString *str;
211
212   str = [NSMutableString stringWithCapacity:64];
213   if (self->condition) [str appendFormat:@" condition=%@", self->condition];
214   if (self->object)    [str appendFormat:@" object=%@",    self->object];
215   if (self->negate)    [str appendFormat:@" negate=%@",    self->negate];
216   if (self->template)  [str appendFormat:@" template=%@",  self->template];
217   return str;
218 }
219
220 @end /* WEQualifierConditional */