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