2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
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
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.
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
23 #include <EOControl/EOQualifier.h>
26 @interface EOQualifier(EvalContext)
27 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx;
30 @implementation EOAndQualifier
32 static BOOL debugEval = NO;
33 static BOOL debugTransform = NO;
36 debugEval = [EOQualifier isEvaluationDebuggingEnabled];
39 - (id)initWithQualifierArray:(NSArray *)_qualifiers {
40 self->count = [_qualifiers count];
41 self->qualifiers = [_qualifiers copyWithZone:[self zone]];
45 - (id)initWithQualifiers:(EOQualifier *)_qual1, ... {
53 for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++)
58 return [self initWithQualifierArray:nil];
60 qs = calloc(c, sizeof(id));
63 for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++) {
68 a = [NSArray arrayWithObjects:qs count:c];
71 return [self initWithQualifierArray:a];
75 [self->qualifiers release];
79 - (NSArray *)qualifiers {
80 return self->qualifiers;
82 - (NSArray *)subqualifiers {
83 return [self qualifiers];
88 - (EOQualifier *)qualifierWithBindings:(NSDictionary *)_bindings
89 requiresAllVariables:(BOOL)_reqAll
92 id objects[self->count + 1];
94 id (*objAtIdx)(id,SEL,unsigned);
97 [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
99 for (i = 0; i < self->count; i++) {
102 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
103 newq = [q qualifierWithBindings:_bindings requiresAllVariables:_reqAll];
104 if (newq == nil) newq = q;
109 array = [NSArray arrayWithObjects:objects count:self->count];
110 return [[[[self class] alloc] initWithQualifierArray:array] autorelease];
113 - (NSArray *)bindingKeys {
114 NSMutableSet *keys = nil;
118 objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
120 for (i = 0; i < self->count; i++) {
124 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
125 qb = [q bindingKeys];
127 if ([qb count] > 0) {
128 if (keys == nil) keys = [NSMutableSet setWithCapacity:16];
129 [keys addObjectsFromArray:qb];
133 return keys ? [keys allObjects] : [NSArray array];
138 - (void)addQualifierKeysToSet:(NSMutableSet *)_keys {
140 [self->qualifiers makeObjectsPerformSelector:_cmd withObject:_keys];
145 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx {
149 if ((_ctx == nil) && (self->count > 1))
150 _ctx = [NSMutableDictionary dictionaryWithCapacity:16];
152 objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
154 for (i = 0; i < self->count; i++) {
157 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
159 if (![q evaluateWithObject:_object inEvalContext:_ctx]) {
161 NSLog(@"Eval: EOAndQualifier '%@':\n qualifier[%i]: '%@'\n"
162 @" failed on object '%@'",
163 self, i+1, q, _object);
169 NSLog(@"Eval: EOAndQualifier '%@':\n true on object '%@'",
174 - (BOOL)evaluateWithObject:(id)_object {
175 return [self evaluateWithObject:_object inEvalContext:nil];
180 - (void)encodeWithCoder:(NSCoder *)_coder {
181 [_coder encodeObject:self->qualifiers];
183 - (id)initWithCoder:(NSCoder *)_coder {
184 self->qualifiers = [[_coder decodeObject] retain];
190 - (BOOL)isEqualToQualifier:(EOQualifier *)_qual {
191 return [self->qualifiers isEqualToArray:[(EOAndQualifier *)_qual qualifiers]];
196 - (EOQualifier *)qualifierByApplyingTransformer:(id)_transformer
199 if ([_transformer respondsToSelector:
200 @selector(transformAndQualifier:inContext:)]) {
202 NSLog(@"transformer: %@\n transform: %@", _transformer, self);
203 return [_transformer transformAndQualifier:self inContext:_ctx];
210 BOOL didTransform = NO;
212 if (debugTransform) {
213 NSLog(@"EOAndQualifier: transform %i using %@ ...",
214 self->count, _transformer);
217 qs = calloc(self->count + 1, sizeof(id));
218 for (i = 0; i < self->count; i++) {
221 q = [self->qualifiers objectAtIndex:i];
222 qs[i] = [q qualifierByApplyingTransformer:_transformer inContext:_ctx];
225 else if (qs[i] != q) {
227 NSLog(@"EOAndQualifier: subqualifier %i did transform", i);
230 else if (debugTransform)
231 NSLog(@"EOAndQualifier: subqualifier %i did not transform", i);
234 a = [[NSArray alloc] initWithObjects:qs count:self->count];
236 aq = [[EOAndQualifier alloc] initWithQualifierArray:a];
238 return [aq autorelease];
242 return [[self retain] autorelease];
247 - (EOQualifier *)qualifierByApplyingKeyMap:(NSDictionary *)_map {
253 qs = calloc(self->count + 1, sizeof(id));
254 for (i = 0; i < self->count; i++) {
257 q = [self->qualifiers objectAtIndex:i];
258 qs[i] = [q qualifierByApplyingKeyMap:_map];
259 if (qs[i] == nil) qs[i] = q;
261 a = [[NSArray alloc] initWithObjects:qs count:self->count];
263 aq = [[EOAndQualifier alloc] initWithQualifierArray:a];
265 return [aq autorelease];
270 - (NSString *)description {
275 sd = [self->qualifiers valueForKey:@"qualifierDescription"];
276 if ((len = [sd count]) == 0)
279 return [sd objectAtIndex:0];
281 ms = [NSMutableString stringWithCapacity:(len * 16)];
282 [ms appendString:@"("];
283 for (i = 0; i < len; i++) {
284 if (i != 0) [ms appendString:@" AND "];
285 [ms appendString:[sd objectAtIndex:i]];
287 [ms appendString:@")"];
291 @end /* EOAndQualifier */