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>
23 #include <EOControl/EONull.h>
26 @interface NSObject(QualifierDescription)
27 - (NSString *)qualifierDescription;
30 @implementation EOKeyValueQualifier
32 static BOOL debugEval = NO;
33 static BOOL debugTransform = NO;
34 static EONull *null = nil;
38 null = [[EONull null] retain];
39 debugEval = [EOQualifier isEvaluationDebuggingEnabled];
42 - (id)initWithKey:(NSString *)_key
43 operatorSelector:(SEL)_selector
46 self->key = [_key copyWithZone:NULL];
47 self->value = [_value retain];
48 self->operator = _selector;
54 [self->value release];
64 return self->operator;
72 - (EOQualifier *)qualifierWithBindings:(NSDictionary *)_bindings
73 requiresAllVariables:(BOOL)_reqAll
75 static Class VarClass = Nil;
80 if (VarClass == Nil) VarClass = [EOQualifierVariable class];
83 if ([self->key class] == VarClass) {
84 newKey = [_bindings objectForKey:[(EOQualifierVariable *)self->key key]];
98 if ([self->value class] == VarClass) {
99 newValue = [_bindings objectForKey:[self->value key]];
100 if (newValue == nil) {
105 newValue = self->value;
111 newValue = self->value;
116 return [[[[self class] alloc]
118 operatorSelector:self->operator
119 value:newValue] autorelease];
122 - (NSArray *)bindingKeys {
123 static Class VarClass = Nil;
124 Class keyClass, vClass;
125 if (VarClass == Nil) VarClass = [EOQualifierVariable class];
127 keyClass = [self->key class];
128 vClass = [self->value class];
130 if ((keyClass == VarClass) && (vClass == VarClass)) {
132 o[0] = [(EOQualifierVariable *)self->key key];
133 o[1] = [(EOQualifierVariable *)self->value key];
134 return [NSArray arrayWithObjects:o count:2];
137 if (keyClass == VarClass)
138 return [NSArray arrayWithObject:[(EOQualifierVariable *)self->key key]];
139 if (vClass == VarClass)
140 return [NSArray arrayWithObject:[(EOQualifierVariable *)self->value key]];
142 return [NSArray array];
147 - (void)addQualifierKeysToSet:(NSMutableSet *)_keys {
149 [_keys addObject:self->key];
154 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx {
156 BOOL (*m)(id, SEL, id);
160 _ctx = [NSMutableDictionary dictionaryWithCapacity:16];
162 if ((lv = [(NSDictionary *)_ctx objectForKey:self->key]) == nil) {
163 lv = [_object valueForKeyPath:self->key];
164 if (lv == nil) lv = null;
165 [(NSMutableDictionary *)_ctx setObject:lv forKey:self->key];
168 rv = self->value ? self->value : null;
171 NSLog(@"Eval: EOKeyValueQualifier:(%@ %@)\n"
172 @" compare %@<%@>\n with %@<%@>",
173 self->key, NSStringFromSelector(self->operator),
174 lv, NSStringFromClass([lv class]),
175 rv, NSStringFromClass([rv class]));
178 if ((m = (void *)[lv methodForSelector:self->operator]) == NULL) {
179 /* no such operator method ! */
180 [lv doesNotRecognizeSelector:self->operator];
184 result = m(lv, self->operator, rv);
186 NSLog(@" %@", result ? @"MATCHES" : @"DOES NOT MATCH");
189 - (BOOL)evaluateWithObject:(id)_object {
190 return [self evaluateWithObject:_object inEvalContext:nil];
195 - (void)encodeWithCoder:(NSCoder *)_coder {
196 [_coder encodeObject:self->key];
197 [_coder encodeObject:self->value];
198 [_coder encodeValueOfObjCType:@encode(SEL) at:&(self->operator)];
200 - (id)initWithCoder:(NSCoder *)_coder {
201 self->key = [[_coder decodeObject] copyWithZone:[self zone]];
202 self->value = [[_coder decodeObject] retain];
203 [_coder decodeValueOfObjCType:@encode(SEL) at:&(self->operator)];
209 - (BOOL)isEqualToQualifier:(EOQualifier *)_qual {
210 if (![self->key isEqual:[(EOKeyValueQualifier *)_qual key]])
212 if (![self->value isEqual:[(EOKeyValueQualifier *)_qual value]])
214 if (sel_eq(self->operator, [(EOKeyValueQualifier *)_qual selector]))
221 - (EOQualifier *)qualifierByApplyingTransformer:(id)_transformer
224 if ([_transformer respondsToSelector:
225 @selector(transformKeyValueQualifier:inContext:)]) {
227 NSLog(@"transformer: %@\n transform: %@", _transformer, self);
228 return [_transformer transformKeyValueQualifier:self inContext:_ctx];
232 NSLog(@"EOKeyValueQualifier: not transforming using %@", _transformer);
233 return [[self retain] autorelease];
237 - (EOQualifier *)qualifierByApplyingKeyMap:(NSDictionary *)_map {
238 EOKeyValueQualifier *kvq;
241 k = [_map objectForKey:self->key];
242 if (k == nil) k = self->key;
244 kvq = [[EOKeyValueQualifier alloc]
245 initWithKey:k operatorSelector:self->operator value:self->value];
246 return [kvq autorelease];
249 /* key/value archiving */
251 - (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
252 if ((self = [super initWithKeyValueUnarchiver:_unarchiver]) != nil) {
255 self->key = [[_unarchiver decodeObjectForKey:@"key"] copy];
256 self->value = [[_unarchiver decodeObjectForKey:@"value"] retain];
258 if ((s = [_unarchiver decodeObjectForKey:@"selectorName"]) != nil) {
259 if (![s hasSuffix:@":"]) s = [s stringByAppendingString:@":"];
260 self->operator = NSSelectorFromString(s);
262 else if ((s = [_unarchiver decodeObjectForKey:@"selector"]) != nil)
263 self->operator = NSSelectorFromString(s);
267 - (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver {
270 [super encodeWithKeyValueArchiver:_archiver];
272 [_archiver encodeObject:[self key] forKey:@"key"];
273 [_archiver encodeObject:[self value] forKey:@"value"];
275 s = NSStringFromSelector([self selector]);
276 if ([s hasSuffix:@":"]) s = [s substringToIndex:[s length] - 1];
277 [_archiver encodeObject:s forKey:@"selectorName"];
282 - (NSString *)description {
285 s = [NSMutableString stringWithCapacity:64];
286 [s appendString:self->key];
287 [s appendString:@" "];
288 [s appendString:[EOQualifier stringForOperatorSelector:self->operator]];
289 [s appendString:@" "];
290 [s appendString:[self->value qualifierDescription]];
294 @end /* EOKeyValueQualifier */