2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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>
24 #include <EOControl/EONull.h>
27 @interface NSObject(QualifierDescription)
28 - (NSString *)qualifierDescription;
31 @implementation EOKeyValueQualifier
33 static BOOL debugEval = NO;
34 static BOOL debugTransform = NO;
35 static EONull *null = nil;
39 null = [[EONull null] retain];
40 debugEval = [EOQualifier isEvaluationDebuggingEnabled];
43 - (id)initWithKey:(NSString *)_key
44 operatorSelector:(SEL)_selector
47 self->key = [_key copyWithZone:NULL];
48 self->value = [_value retain];
49 self->operator = _selector;
55 [self->value release];
65 return self->operator;
73 - (EOQualifier *)qualifierWithBindings:(NSDictionary *)_bindings
74 requiresAllVariables:(BOOL)_reqAll
76 static Class VarClass = Nil;
81 if (VarClass == Nil) VarClass = [EOQualifierVariable class];
84 if ([self->key class] == VarClass) {
85 newKey = [_bindings objectForKey:[(EOQualifierVariable *)self->key key]];
99 if ([self->value class] == VarClass) {
100 newValue = [_bindings objectForKey:[self->value key]];
101 if (newValue == nil) {
106 newValue = self->value;
112 newValue = self->value;
117 return [[[[self class] alloc]
119 operatorSelector:self->operator
120 value:newValue] autorelease];
123 - (NSArray *)bindingKeys {
124 static Class VarClass = Nil;
125 Class keyClass, vClass;
126 if (VarClass == Nil) VarClass = [EOQualifierVariable class];
128 keyClass = [self->key class];
129 vClass = [self->value class];
131 if ((keyClass == VarClass) && (vClass == VarClass)) {
133 o[0] = [(EOQualifierVariable *)self->key key];
134 o[1] = [(EOQualifierVariable *)self->value key];
135 return [NSArray arrayWithObjects:o count:2];
138 if (keyClass == VarClass)
139 return [NSArray arrayWithObject:[(EOQualifierVariable *)self->key key]];
140 if (vClass == VarClass)
141 return [NSArray arrayWithObject:[(EOQualifierVariable *)self->value key]];
143 return [NSArray array];
148 - (void)addQualifierKeysToSet:(NSMutableSet *)_keys {
150 [_keys addObject:self->key];
155 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx {
157 BOOL (*m)(id, SEL, id);
161 _ctx = [NSMutableDictionary dictionaryWithCapacity:16];
163 if ((lv = [(NSDictionary *)_ctx objectForKey:self->key]) == nil) {
164 lv = [_object valueForKeyPath:self->key];
165 if (lv == nil) lv = null;
166 [(NSMutableDictionary *)_ctx setObject:lv forKey:self->key];
169 rv = self->value ? self->value : null;
172 NSLog(@"Eval: EOKeyValueQualifier:(%@ %@)\n"
173 @" compare %@<%@>\n with %@<%@>",
174 self->key, NSStringFromSelector(self->operator),
175 lv, NSStringFromClass([lv class]),
176 rv, NSStringFromClass([rv class]));
179 if ((m = (void *)[lv methodForSelector:self->operator]) == NULL) {
180 /* no such operator method ! */
181 [lv doesNotRecognizeSelector:self->operator];
185 result = m(lv, self->operator, rv);
187 NSLog(@" %@", result ? @"MATCHES" : @"DOES NOT MATCH");
190 - (BOOL)evaluateWithObject:(id)_object {
191 return [self evaluateWithObject:_object inEvalContext:nil];
196 - (void)encodeWithCoder:(NSCoder *)_coder {
197 [_coder encodeObject:self->key];
198 [_coder encodeObject:self->value];
199 [_coder encodeValueOfObjCType:@encode(SEL) at:&(self->operator)];
201 - (id)initWithCoder:(NSCoder *)_coder {
202 self->key = [[_coder decodeObject] copyWithZone:[self zone]];
203 self->value = [[_coder decodeObject] retain];
204 [_coder decodeValueOfObjCType:@encode(SEL) at:&(self->operator)];
210 - (BOOL)isEqualToQualifier:(EOQualifier *)_qual {
211 if (![self->key isEqual:[(EOKeyValueQualifier *)_qual key]])
213 if (![self->value isEqual:[(EOKeyValueQualifier *)_qual value]])
215 if (sel_eq(self->operator, [(EOKeyValueQualifier *)_qual selector]))
222 - (EOQualifier *)qualifierByApplyingTransformer:(id)_transformer
225 if ([_transformer respondsToSelector:
226 @selector(transformKeyValueQualifier:inContext:)]) {
228 NSLog(@"transformer: %@\n transform: %@", _transformer, self);
229 return [_transformer transformKeyValueQualifier:self inContext:_ctx];
233 NSLog(@"EOKeyValueQualifier: not transforming using %@", _transformer);
234 return [[self retain] autorelease];
238 - (EOQualifier *)qualifierByApplyingKeyMap:(NSDictionary *)_map {
239 EOKeyValueQualifier *kvq;
242 k = [_map objectForKey:self->key];
243 if (k == nil) k = self->key;
245 kvq = [[EOKeyValueQualifier alloc]
246 initWithKey:k operatorSelector:self->operator value:self->value];
247 return [kvq autorelease];
252 - (NSString *)description {
255 s = [NSMutableString stringWithCapacity:64];
256 [s appendString:self->key];
257 [s appendString:@" "];
258 [s appendString:[EOQualifier stringForOperatorSelector:self->operator]];
259 [s appendString:@" "];
260 [s appendString:[self->value qualifierDescription]];
264 @end /* EOKeyValueQualifier */