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