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 EOOrQualifier
31 //static BOOL debugEval = NO;
32 static BOOL debugTransform = NO;
34 - (id)initWithQualifierArray:(NSArray *)_qualifiers {
35 self->count = [_qualifiers count];
36 self->qualifiers = [_qualifiers copyWithZone:[self zone]];
40 - (id)initWithQualifiers:(EOQualifier *)_qual1, ... {
48 for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++)
53 return [self initWithQualifierArray:nil];
55 qs = objc_calloc(c, sizeof(id));
58 for (c = 0, q = _qual1; q != nil; q = va_arg(va, id), c++) {
63 a = [NSArray arrayWithObjects:qs count:c];
66 return [self initWithQualifierArray:a];
70 [self->qualifiers release];
76 - (NSArray *)qualifiers {
77 return self->qualifiers;
79 - (NSArray *)subqualifiers {
80 return [self qualifiers];
85 - (EOQualifier *)qualifierWithBindings:(NSDictionary *)_bindings
86 requiresAllVariables:(BOOL)_reqAll
89 id objects[self->count + 1];
94 objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
96 for (i = 0; i < self->count; i++) {
99 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
100 newq = [q qualifierWithBindings:_bindings requiresAllVariables:_reqAll];
101 if (newq == nil) newq = q;
106 array = [NSArray arrayWithObjects:objects count:self->count];
107 return [[[[self class] alloc] initWithQualifierArray:array] autorelease];
110 - (NSArray *)bindingKeys {
111 NSMutableSet *keys = nil;
115 objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
117 for (i = 0; i < self->count; i++) {
121 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
122 qb = [q bindingKeys];
124 if ([qb count] > 0) {
125 if (keys == nil) keys = [NSMutableSet setWithCapacity:16];
126 [keys addObjectsFromArray:qb];
130 return keys ? [keys allObjects] : (NSArray *)[NSArray array];
135 - (void)addQualifierKeysToSet:(NSMutableSet *)_keys {
137 [self->qualifiers makeObjectsPerformSelector:_cmd withObject:_keys];
142 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx {
146 if ((_ctx == nil) && (self->count > 1))
147 _ctx = [NSMutableDictionary dictionaryWithCapacity:16];
149 objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)];
151 for (i = 0; i < self->count; i++) {
154 q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i);
155 if ([q evaluateWithObject:_object inEvalContext:_ctx])
160 - (BOOL)evaluateWithObject:(id)_object {
161 return [self evaluateWithObject:_object inEvalContext:nil];
166 - (void)encodeWithCoder:(NSCoder *)_coder {
167 [_coder encodeObject:self->qualifiers];
169 - (id)initWithCoder:(NSCoder *)_coder {
170 self->qualifiers = [[_coder decodeObject] retain];
176 - (BOOL)isEqualToQualifier:(EOQualifier *)_qual {
177 return [self->qualifiers isEqualToArray:[(EOOrQualifier *)_qual qualifiers]];
182 - (EOQualifier *)qualifierByApplyingTransformer:(id)_transformer
185 if ([_transformer respondsToSelector:
186 @selector(transformOrQualifier:inContext:)]) {
188 NSLog(@"transformer: %@\n transform: %@", _transformer, self);
189 return [_transformer transformOrQualifier:self inContext:_ctx];
196 BOOL didTransform = NO;
198 if (debugTransform) {
199 NSLog(@"EOOrQualifier: transform %i using %@ ...",
200 self->count, _transformer);
203 qs = calloc(self->count + 1, sizeof(id));
204 for (i = 0; i < self->count; i++) {
207 q = [self->qualifiers objectAtIndex:i];
208 qs[i] = [q qualifierByApplyingTransformer:_transformer inContext:_ctx];
211 else if (qs[i] != q) {
213 NSLog(@"EOOrQualifier: subqualifier %i did transform", i);
216 else if (debugTransform)
217 NSLog(@"EOOrQualifier: subqualifier %i did not transform", i);
220 a = [[NSArray alloc] initWithObjects:qs count:self->count];
222 aq = [[EOOrQualifier alloc] initWithQualifierArray:a];
224 return [aq autorelease];
228 return [[self retain] autorelease];
233 - (EOQualifier *)qualifierByApplyingKeyMap:(NSDictionary *)_map {
239 qs = calloc(self->count + 1, sizeof(id));
240 for (i = 0; i < self->count; i++) {
243 q = [self->qualifiers objectAtIndex:i];
244 qs[i] = [q qualifierByApplyingKeyMap:_map];
245 if (qs[i] == nil) qs[i] = q;
247 a = [[NSArray alloc] initWithObjects:qs count:self->count];
249 aq = [[EOOrQualifier alloc] initWithQualifierArray:a];
251 return [aq autorelease];
254 /* key/value archiving */
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];
263 - (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver {
264 [super encodeWithKeyValueArchiver:_archiver];
265 [_archiver encodeObject:[self qualifiers] forKey:@"qualifiers"];
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:@" OR "];
285 [ms appendString:[sd objectAtIndex:i]];
287 [ms appendString:@")"];
291 @end /* EOOrQualifier */