]> err.no Git - sope/blob - sope-core/EOControl/EOOrQualifier.m
renamed packages as discussed in the developer list
[sope] / sope-core / EOControl / EOOrQualifier.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
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 #include <EOControl/EOQualifier.h>
24 #include "common.h"
25
26 @interface EOQualifier(EvalContext)
27 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx;
28 @end
29
30 @implementation EOOrQualifier
31
32 //static BOOL debugEval      = NO;
33 static BOOL debugTransform = NO;
34
35 - (id)initWithQualifierArray:(NSArray *)_qualifiers {
36   self->count      = [_qualifiers count];
37   self->qualifiers = [_qualifiers copyWithZone:[self zone]];
38   return self;
39 }
40
41 - (id)initWithQualifiers:(EOQualifier *)_qual1, ... {
42   va_list va;
43   EOQualifier *q;
44   id *qs;
45   unsigned c;
46   NSArray *a;
47   
48   va_start(va, _qual1);
49   for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++)
50     ;
51   va_end(va);
52
53   if (c == 0)
54     return [self initWithQualifierArray:nil];
55
56   qs = objc_calloc(c, sizeof(id));
57   
58   va_start(va, _qual1);
59   for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++) {
60     qs[c] = q;
61   }
62   va_end(va);
63
64   a = [NSArray arrayWithObjects:qs count:c];
65   objc_free(qs);
66   
67   return [self initWithQualifierArray:a];
68 }
69
70 - (void)dealloc {
71   [self->qualifiers release];
72   [super dealloc];
73 }
74
75 /* accessors */
76
77 - (NSArray *)qualifiers {
78   return self->qualifiers;
79 }
80 - (NSArray *)subqualifiers {
81   return [self qualifiers];
82 }
83
84 /* bindings */
85
86 - (EOQualifier *)qualifierWithBindings:(NSDictionary *)_bindings
87   requiresAllVariables:(BOOL)_reqAll
88 {
89   NSArray  *array;
90   id       objects[self->count + 1];
91   unsigned i;
92
93   IMP objAtIdx;
94
95   objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
96   
97   for (i = 0; i < self->count; i++) {
98     id q, newq;
99
100     q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
101     newq = [q qualifierWithBindings:_bindings requiresAllVariables:_reqAll];
102     if (newq == nil) newq = q;
103     
104     objects[i] = newq;
105   }
106
107   array = [NSArray arrayWithObjects:objects count:self->count];
108   return [[[[self class] alloc] initWithQualifierArray:array] autorelease];
109 }
110
111 - (NSArray *)bindingKeys {
112   NSMutableSet *keys = nil;
113   unsigned i;
114   IMP objAtIdx;
115
116   objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
117   
118   for (i = 0; i < self->count; i++) {
119     NSArray *qb;
120     id q;
121
122     q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
123     qb = [q bindingKeys];
124
125     if ([qb count] > 0) {
126       if (keys == nil) keys = [NSMutableSet setWithCapacity:16];
127       [keys addObjectsFromArray:qb];
128     }
129   }
130   
131   return keys ? [keys allObjects] : [NSArray array];
132 }
133
134 /* keys */
135
136 - (void)addQualifierKeysToSet:(NSMutableSet *)_keys {
137   /* new in WO 4.5 */
138   [self->qualifiers makeObjectsPerformSelector:_cmd withObject:_keys];
139 }
140
141 /* evaluation */
142
143 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx {
144   unsigned i;
145   IMP objAtIdx;
146   
147   if ((_ctx == nil) && (self->count > 1))
148     _ctx = [NSMutableDictionary dictionaryWithCapacity:16];
149   
150   objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
151   
152   for (i = 0; i < self->count; i++) {
153     id q;
154     
155     q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
156     if ([q evaluateWithObject:_object inEvalContext:_ctx])
157       return YES;
158   }
159   return NO;
160 }
161 - (BOOL)evaluateWithObject:(id)_object {
162   return [self evaluateWithObject:_object inEvalContext:nil];
163 }
164
165 /* NSCoding */
166
167 - (void)encodeWithCoder:(NSCoder *)_coder {
168   [_coder encodeObject:self->qualifiers];
169 }
170 - (id)initWithCoder:(NSCoder *)_coder {
171   self->qualifiers = [[_coder decodeObject] retain];
172   return self;
173 }
174
175 /* Comparing */
176
177 - (BOOL)isEqualToQualifier:(EOQualifier *)_qual {
178   return [self->qualifiers isEqualToArray:[(EOOrQualifier *)_qual qualifiers]];
179 }
180
181 /* remapping keys */
182
183 - (EOQualifier *)qualifierByApplyingTransformer:(id)_transformer
184   inContext:(id)_ctx
185 {
186   if ([_transformer respondsToSelector:
187                       @selector(transformOrQualifier:inContext:)]) {
188     if (debugTransform)
189       NSLog(@"transformer: %@\n  transform: %@", _transformer, self);
190     return [_transformer transformOrQualifier:self inContext:_ctx];
191   }
192   else {
193     EOOrQualifier *aq;
194     NSArray  *a;
195     id       *qs;
196     unsigned i;
197     BOOL     didTransform = NO;
198     
199     if (debugTransform) {
200       NSLog(@"EOOrQualifier: transform %i using %@ ...", 
201             self->count, _transformer);
202     }
203     
204     qs = calloc(self->count + 1, sizeof(id));
205     for (i = 0; i < self->count; i++) {
206       EOQualifier *q;
207       
208       q     = [self->qualifiers objectAtIndex:i];
209       qs[i] = [q qualifierByApplyingTransformer:_transformer inContext:_ctx];
210       if (qs[i] == nil) 
211         qs[i] = q;
212       else if (qs[i] != q) {
213         if (debugTransform)
214           NSLog(@"EOOrQualifier:   subqualifier %i did transform", i);
215         didTransform = YES;
216       }
217       else if (debugTransform)
218         NSLog(@"EOOrQualifier:   subqualifier %i did not transform", i);
219     }
220     if (didTransform) {
221       a = [[NSArray alloc] initWithObjects:qs count:self->count];
222       if (qs) free(qs);
223       aq = [[EOOrQualifier alloc] initWithQualifierArray:a];
224       [a release];
225       return [aq autorelease];
226     }
227     else {
228       if (qs) free(qs);
229       return [[self retain] autorelease];
230     }
231   }
232 }
233
234 - (EOQualifier *)qualifierByApplyingKeyMap:(NSDictionary *)_map {
235   EOOrQualifier *aq;
236   NSArray  *a;
237   id       *qs;
238   unsigned i;
239   
240   qs = calloc(self->count + 1, sizeof(id));
241   for (i = 0; i < self->count; i++) {
242     EOQualifier *q;
243     
244     q     = [self->qualifiers objectAtIndex:i];
245     qs[i] = [q qualifierByApplyingKeyMap:_map];
246     if (qs[i] == nil) qs[i] = q;
247   }
248   a = [[NSArray alloc] initWithObjects:qs count:self->count];
249   if (qs) free(qs);
250   aq = [[EOOrQualifier alloc] initWithQualifierArray:a];
251   [a release];
252   return [aq autorelease];
253 }
254
255 /* description */
256
257 - (NSString *)description {
258   NSMutableString *ms;
259   NSArray  *sd;
260   unsigned i, len;
261   
262   sd = [self->qualifiers valueForKey:@"qualifierDescription"];
263   if ((len = [sd count]) == 0)
264     return nil;
265   if (len == 1)
266     return [sd objectAtIndex:0];
267   
268   ms = [NSMutableString stringWithCapacity:(len * 16)];
269   [ms appendString:@"("];
270   for (i = 0; i < len; i++) {
271     if (i != 0) [ms appendString:@" OR "];
272     [ms appendString:[sd objectAtIndex:i]];
273   }
274   [ms appendString:@")"];
275   return ms;
276 }
277
278 @end /* EOOrQualifier */