2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include <EOControl/EOQualifier.h>
25 @interface EOQualifier(EvalContext)
26 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx;
29 @implementation EOAndQualifier
31 static BOOL debugEval = NO;
32 static BOOL debugTransform = NO;
35 debugEval = [EOQualifier isEvaluationDebuggingEnabled];
38 - (id)initWithQualifierArray:(NSArray *)_qualifiers {
39 self->count = [_qualifiers count];
40 self->qualifiers = [_qualifiers copyWithZone:[self zone]];
44 - (id)initWithQualifiers:(EOQualifier *)_qual1, ... {
52 for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++)
57 return [self initWithQualifierArray:nil];
59 qs = calloc(c, sizeof(id));
62 for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++) {
67 a = [NSArray arrayWithObjects:qs count:c];
70 return [self initWithQualifierArray:a];
74 [self->qualifiers release];
78 - (NSArray *)qualifiers {
79 return self->qualifiers;
81 - (NSArray *)subqualifiers {
82 return [self qualifiers];
87 - (EOQualifier *)qualifierWithBindings:(NSDictionary *)_bindings
88 requiresAllVariables:(BOOL)_reqAll
91 id objects[self->count + 1];
93 id (*objAtIdx)(id,SEL,unsigned);
96 [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
98 for (i = 0; i < self->count; i++) {
101 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
102 newq = [q qualifierWithBindings:_bindings requiresAllVariables:_reqAll];
103 if (newq == nil) newq = q;
108 array = [NSArray arrayWithObjects:objects count:self->count];
109 return [[[[self class] alloc] initWithQualifierArray:array] autorelease];
112 - (NSArray *)bindingKeys {
113 NSMutableSet *keys = nil;
117 objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
119 for (i = 0; i < self->count; i++) {
123 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
124 qb = [q bindingKeys];
126 if ([qb count] > 0) {
127 if (keys == nil) keys = [NSMutableSet setWithCapacity:16];
128 [keys addObjectsFromArray:qb];
132 return keys ? [keys allObjects] : (NSArray *)[NSArray array];
137 - (void)addQualifierKeysToSet:(NSMutableSet *)_keys {
139 [self->qualifiers makeObjectsPerformSelector:_cmd withObject:_keys];
144 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx {
148 if ((_ctx == nil) && (self->count > 1))
149 _ctx = [NSMutableDictionary dictionaryWithCapacity:16];
151 objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
153 for (i = 0; i < self->count; i++) {
156 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
158 if (![q evaluateWithObject:_object inEvalContext:_ctx]) {
160 NSLog(@"Eval: EOAndQualifier '%@':\n qualifier[%i]: '%@'\n"
161 @" failed on object '%@'",
162 self, i+1, q, _object);
168 NSLog(@"Eval: EOAndQualifier '%@':\n true on object '%@'",
173 - (BOOL)evaluateWithObject:(id)_object {
174 return [self evaluateWithObject:_object inEvalContext:nil];
179 - (void)encodeWithCoder:(NSCoder *)_coder {
180 [_coder encodeObject:self->qualifiers];
182 - (id)initWithCoder:(NSCoder *)_coder {
183 self->qualifiers = [[_coder decodeObject] retain];
189 - (BOOL)isEqualToQualifier:(EOQualifier *)_qual {
190 return [self->qualifiers isEqualToArray:[(EOAndQualifier *)_qual qualifiers]];
195 - (EOQualifier *)qualifierByApplyingTransformer:(id)_transformer
198 if ([_transformer respondsToSelector:
199 @selector(transformAndQualifier:inContext:)]) {
201 NSLog(@"transformer: %@\n transform: %@", _transformer, self);
202 return [_transformer transformAndQualifier:self inContext:_ctx];
209 BOOL didTransform = NO;
211 if (debugTransform) {
212 NSLog(@"EOAndQualifier: transform %i using %@ ...",
213 self->count, _transformer);
216 qs = calloc(self->count + 1, sizeof(id));
217 for (i = 0; i < self->count; i++) {
220 q = [self->qualifiers objectAtIndex:i];
221 qs[i] = [q qualifierByApplyingTransformer:_transformer inContext:_ctx];
224 else if (qs[i] != q) {
226 NSLog(@"EOAndQualifier: subqualifier %i did transform", i);
229 else if (debugTransform)
230 NSLog(@"EOAndQualifier: subqualifier %i did not transform", i);
233 a = [[NSArray alloc] initWithObjects:qs count:self->count];
235 aq = [[EOAndQualifier alloc] initWithQualifierArray:a];
237 return [aq autorelease];
241 return [[self retain] autorelease];
246 - (EOQualifier *)qualifierByApplyingKeyMap:(NSDictionary *)_map {
252 qs = calloc(self->count + 1, sizeof(id));
253 for (i = 0; i < self->count; i++) {
256 q = [self->qualifiers objectAtIndex:i];
257 qs[i] = [q qualifierByApplyingKeyMap:_map];
258 if (qs[i] == nil) qs[i] = q;
260 a = [[NSArray alloc] initWithObjects:qs count:self->count];
262 aq = [[EOAndQualifier alloc] initWithQualifierArray:a];
264 return [aq autorelease];
267 /* key/value archiving */
269 - (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
270 if ((self = [super initWithKeyValueUnarchiver:_unarchiver]) != nil) {
271 self->qualifiers = [[_unarchiver decodeObjectForKey:@"qualifiers"] copy];
272 self->count = [self->qualifiers count];
276 - (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver {
277 [super encodeWithKeyValueArchiver:_archiver];
278 [_archiver encodeObject:[self qualifiers] forKey:@"qualifiers"];
283 - (NSString *)description {
288 sd = [self->qualifiers valueForKey:@"qualifierDescription"];
289 if ((len = [sd count]) == 0)
292 return [sd objectAtIndex:0];
294 ms = [NSMutableString stringWithCapacity:(len * 16)];
295 [ms appendString:@"("];
296 for (i = 0; i < len; i++) {
297 if (i != 0) [ms appendString:@" AND "];
298 [ms appendString:[sd objectAtIndex:i]];
300 [ms appendString:@")"];
304 @end /* EOAndQualifier */