]> err.no Git - sope/blob - sope-core/EOControl/EOKeyComparisonQualifier.m
Drop apache 1 build-dependency
[sope] / sope-core / EOControl / EOKeyComparisonQualifier.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include <EOControl/EOQualifier.h>
23 #include <EOControl/EONull.h>
24 #include "common.h"
25
26 @implementation EOKeyComparisonQualifier
27
28 static EONull *null = nil;
29
30 + (void)initialize {
31   if (null == nil)
32     null = [[EONull null] retain];
33 }
34
35 - (id)initWithLeftKey:(NSString *)_leftKey
36   operatorSelector:(SEL)_selector
37   rightKey:(NSString *)_rightKey;
38 {
39   self->leftKey  = [_leftKey  copyWithZone:NULL];
40   self->rightKey = [_rightKey copyWithZone:NULL];
41   self->operator = _selector;
42   return self;
43 }
44
45 - (void)dealloc {
46   [self->leftKey  release];
47   [self->rightKey release];
48   [super dealloc];
49 }
50
51 /* accessors */
52
53 - (NSString *)leftKey {
54   return self->leftKey;
55 }
56 - (NSString *)rightKey {
57   return self->rightKey;
58 }
59 - (SEL)selector {
60   return self->operator;
61 }
62
63 /* bindings */
64
65 - (EOQualifier *)qualifierWithBindings:(NSDictionary *)_bindings
66   requiresAllVariables:(BOOL)_reqAll
67 {
68   static Class VarClass = Nil;
69   NSString *newLeftKey;
70   id       newRightKey;
71   BOOL     needNew;
72   
73   if (VarClass == Nil) VarClass = [EOQualifierVariable class];
74   needNew = NO;
75
76   if ([self->leftKey class] == VarClass) {
77     newLeftKey =
78       [_bindings objectForKey:[(EOQualifierVariable *)self->leftKey key]];
79     if (newLeftKey == nil) {
80       if (_reqAll)
81         // throw exception
82         ;
83       else
84         newLeftKey = self->leftKey;
85     }
86     else
87       needNew = YES;
88   }
89   else
90     newLeftKey = self->leftKey;
91
92   if ([self->rightKey class] == VarClass) {
93     newRightKey =
94       [_bindings objectForKey:[(EOQualifierVariable *)self->rightKey key]];
95     if (newRightKey == nil) {
96       if (_reqAll)
97         // throw exception
98         ;
99       else
100         newRightKey = self->rightKey;
101     }
102     else
103       needNew = YES;
104   }
105   else
106     newRightKey = self->rightKey;
107
108   if (!needNew)
109     return self;
110
111   return [[[[self class] alloc]
112                          initWithLeftKey:newLeftKey
113                          operatorSelector:self->operator
114                          rightKey:newRightKey]
115                          autorelease];
116 }
117
118 - (NSArray *)bindingKeys {
119   static Class VarClass = Nil;
120   Class lkClass, rkClass;
121   if (VarClass == Nil) VarClass = [EOQualifierVariable class];
122   
123   lkClass = [self->leftKey  class];
124   rkClass = [self->rightKey class];
125   
126   if ((lkClass == VarClass) && (rkClass == VarClass)) {
127     id o[2];
128     o[0] = [(EOQualifierVariable *)self->leftKey  key];
129     o[1] = [(EOQualifierVariable *)self->rightKey key];
130     return [NSArray arrayWithObjects:o count:2];
131   }
132   
133   if (lkClass == VarClass)
134     return [NSArray arrayWithObject:[(EOQualifierVariable *)self->leftKey key]];
135   if (rkClass == VarClass) {
136     return [NSArray arrayWithObject:
137                       [(EOQualifierVariable *)self->rightKey key]];
138   }
139   return [NSArray array];
140 }
141
142 /* keys */
143
144 - (void)addQualifierKeysToSet:(NSMutableSet *)_keys {
145   /* new in WO 4.5 */
146   [_keys addObject:self->leftKey];
147   [_keys addObject:self->rightKey];
148 }
149
150 /* evaluation */
151
152 - (BOOL)evaluateWithObject:(id)_object inEvalContext:(id)_ctx {
153   id   lv, rv;
154   BOOL (*m)(id, SEL, id);
155   
156   if (_ctx == nil)
157     _ctx = [NSMutableDictionary dictionaryWithCapacity:16];
158   
159   if ((lv = [(NSDictionary *)_ctx objectForKey:self->leftKey]) == nil) {
160     lv = [_object valueForKeyPath:self->leftKey];
161     if (lv == nil) lv = null;
162     [(NSMutableDictionary *)_ctx setObject:lv forKey:self->leftKey];
163   }
164   if ((rv = [(NSDictionary *)_ctx objectForKey:self->rightKey]) == nil) {
165     rv = [_object valueForKeyPath:self->rightKey];
166     if (rv == nil) rv = null;
167     [(NSMutableDictionary *)_ctx setObject:rv forKey:self->rightKey];
168   }
169   
170   if ((m = (void *)[lv methodForSelector:self->operator]) == NULL) {
171     /* no such operator method ! */
172     [lv doesNotRecognizeSelector:self->operator];
173     return NO;
174   }
175
176   return m(lv, self->operator, rv);
177 }
178 - (BOOL)evaluateWithObject:(id)_object {
179   return [self evaluateWithObject:_object inEvalContext:nil];
180 }
181
182 /* NSCoding */
183
184 - (void)encodeWithCoder:(NSCoder *)_coder {
185   [_coder encodeObject:self->leftKey];
186   [_coder encodeObject:self->rightKey];
187   [_coder encodeValueOfObjCType:@encode(SEL) at:&(self->operator)];
188 }
189 - (id)initWithCoder:(NSCoder *)_coder {
190   self->leftKey  = [[_coder decodeObject] copyWithZone:[self zone]];
191   self->rightKey = [[_coder decodeObject] copyWithZone:[self zone]];
192   [_coder decodeValueOfObjCType:@encode(SEL) at:&(self->operator)];
193   return self;
194 }
195
196 /* Comparing */
197
198 - (BOOL)isEqualToQualifier:(EOQualifier *)_qual {
199   if (![self->leftKey isEqual:[(EOKeyComparisonQualifier *)_qual leftKey]])
200     return NO;
201   if (![self->rightKey isEqual:[(EOKeyComparisonQualifier *)_qual rightKey]])
202     return NO;
203   if (sel_eq(self->operator, [(EOKeyComparisonQualifier *)_qual selector]))
204     return YES;
205   return NO;
206 }
207
208 /* remapping keys */
209
210 - (EOQualifier *)qualifierByApplyingTransformer:(id)_transformer
211   inContext:(id)_ctx
212 {
213   if ([_transformer respondsToSelector:
214                       @selector(transformKeyComparisonQualifier:inContext:)]) {
215     return [_transformer transformKeyComparisonQualifier:self inContext:_ctx];
216   }
217   else
218     return [[self retain] autorelease];
219 }
220
221 - (EOQualifier *)qualifierByApplyingKeyMap:(NSDictionary *)_map {
222   EOKeyComparisonQualifier *kcq;
223   NSString *l, *r;
224   
225   l = [_map objectForKey:self->leftKey];
226   if (l == nil) l = self->leftKey;
227   r = [_map objectForKey:self->rightKey];
228   if (r == nil) r = self->rightKey;
229   
230   kcq = [[EOKeyComparisonQualifier alloc] 
231           initWithLeftKey:l operatorSelector:self->operator rightKey:r];
232   return [kcq autorelease];
233 }
234
235 /* key/value archiving */
236
237 - (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
238   if ((self = [super initWithKeyValueUnarchiver:_unarchiver]) != nil) {
239     NSString *s;
240     
241     self->leftKey  = [[_unarchiver decodeObjectForKey:@"leftKey"]  retain];
242     self->rightKey = [[_unarchiver decodeObjectForKey:@"rightKey"] retain];
243
244     if ((s = [_unarchiver decodeObjectForKey:@"selectorName"]) != nil) {
245       if (![s hasSuffix:@":"]) s = [s stringByAppendingString:@":"];
246       self->operator = NSSelectorFromString(s);
247     }
248     else if ((s = [_unarchiver decodeObjectForKey:@"selector"]) != nil)
249       self->operator = NSSelectorFromString(s);
250   }
251   return self;
252 }
253 - (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver {
254   NSString *s;
255   
256   [super encodeWithKeyValueArchiver:_archiver];
257   
258   [_archiver encodeObject:[self leftKey]  forKey:@"leftKey"];
259   [_archiver encodeObject:[self rightKey] forKey:@"rightKey"];
260
261   s = NSStringFromSelector([self selector]);
262   if ([s hasSuffix:@":"]) s = [s substringToIndex:[s length] - 1];
263   [_archiver encodeObject:s forKey:@"selectorName"];
264 }
265
266 /* description */
267
268 - (NSString *)description {
269   NSMutableString *s;
270   
271   s = [NSMutableString stringWithCapacity:64];
272   [s appendString:self->leftKey];
273   [s appendString:@" "];
274   [s appendString:[EOQualifier stringForOperatorSelector:self->operator]];
275   [s appendString:@" "];
276   [s appendString:self->rightKey];
277   return s;
278 }
279
280 @end /* EOKeyComparisonQualifier */