API  0.9.10
CPCompoundPredicate.j
Go to the documentation of this file.
1 /*
2  * CPCompoundPredicate.j
3  *
4  * Portions based on NSCompoundPredicate.m in Cocotron (http://www.cocotron.org/)
5  * Copyright (c) 2006-2007 Christopher J. W. Lloyd
6  *
7  * Created by cacaodev.
8  * Copyright 2010.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 
26 @typedef CPCompoundPredicateType
27 
36 @implementation CPCompoundPredicate : CPPredicate
37 {
38  CPCompoundPredicateType _type;
39  CPArray _predicates;
40 }
41 
42 // Constructors
48 - (id)initWithType:(CPCompoundPredicateType)type subpredicates:(CPArray)predicates
49 {
50  self = [super init];
51 
52  if (self)
53  {
54  _type = type;
55  _predicates = predicates;
56  }
57 
58  return self;
59 }
60 
66 + (CPPredicate)notPredicateWithSubpredicate:(CPPredicate)predicate
67 {
68  return [[self alloc] initWithType:CPNotPredicateType subpredicates:[CPArray arrayWithObject:predicate]];
69 }
70 
76 + (CPPredicate)andPredicateWithSubpredicates:(CPArray)subpredicates
77 {
78  return [[self alloc] initWithType:CPAndPredicateType subpredicates:subpredicates];
79 }
80 
86 + (CPPredicate)orPredicateWithSubpredicates:(CPArray)predicates
87 {
88  return [[self alloc] initWithType:CPOrPredicateType subpredicates:predicates];
89 }
90 
91 // Getting Information About a Compound Predicate
96 - (CPCompoundPredicateType)compoundPredicateType
97 {
98  return _type;
99 }
100 
105 - (CPArray)subpredicates
106 {
107  return _predicates;
108 }
109 
110 - (CPPredicate)predicateWithSubstitutionVariables:(CPDictionary)variables
111 {
112  var subp = [CPArray array],
113  count = [subp count],
114  i = 0;
115 
116  for (; i < count; i++)
117  {
118  var p = [subp objectAtIndex:i],
119  sp = [p predicateWithSubstitutionVariables:variables];
120 
121  [subp addObject:sp];
122  }
123 
124  return [[CPCompoundPredicate alloc] initWithType:_type subpredicates:subp];
125 }
126 
128 {
129  var result = "",
130  args = [CPArray array],
131  count = [_predicates count],
132  i = 0;
133 
134  if (count == 0)
135  return @"TRUEPREDICATE";
136 
137  for (; i < count; i++)
138  {
139  var subpredicate = [_predicates objectAtIndex:i],
140  precedence = [subpredicate predicateFormat];
141 
142  if ([subpredicate isKindOfClass:[CPCompoundPredicate class]] && [[subpredicate subpredicates] count]> 1 && [subpredicate compoundPredicateType] != _type)
143  precedence = [CPString stringWithFormat:@"(%s)",precedence];
144 
145  if (precedence != nil)
146  [args addObject:precedence];
147  }
148 
149  switch (_type)
150  {
151  case CPNotPredicateType: result += "NOT " + [args objectAtIndex:0];
152  break;
153 
154  case CPAndPredicateType: result += [args objectAtIndex:0];
155  var count = [args count];
156  for (var j = 1; j < count; j++)
157  result += " AND " + [args objectAtIndex:j];
158  break;
159 
160  case CPOrPredicateType: result += [args objectAtIndex:0];
161  var count = [args count];
162  for (var j = 1; j < count; j++)
163  result += " OR " + [args objectAtIndex:j];
164  break;
165  }
166 
167  return result;
168 }
169 
170 - (BOOL)evaluateWithObject:(id)object
171 {
172  return [self evaluateWithObject:object substitutionVariables:nil];
173 }
174 
175 - (BOOL)evaluateWithObject:(id)object substitutionVariables:(CPDictionary)variables
176 {
177  var result = NO,
178  count = [_predicates count],
179  i = 0;
180 
181  if (count == 0)
182  return YES;
183 
184  for (; i < count; i++)
185  {
186  var predicate = [_predicates objectAtIndex:i];
187 
188  switch (_type)
189  {
190  case CPNotPredicateType: return ![predicate evaluateWithObject:object substitutionVariables:variables];
191 
192  case CPAndPredicateType: if (i == 0)
193  result = [predicate evaluateWithObject:object substitutionVariables:variables];
194  else
195  result = result && [predicate evaluateWithObject:object substitutionVariables:variables];
196  if (!result)
197  return NO;
198  break;
199 
200  case CPOrPredicateType: if ([predicate evaluateWithObject:object substitutionVariables:variables])
201  return YES;
202  break;
203  }
204  }
205 
206  return result;
207 }
208 
209 - (BOOL)isEqual:(id)anObject
210 {
211  if (self === anObject)
212  return YES;
213 
214  if (anObject === nil || anObject.isa !== self.isa || _type !== [anObject compoundPredicateType] || ![_predicates isEqualToArray:[anObject subpredicates]])
215  return NO;
216 
217  return YES;
218 }
219 
220 @end
221 
223 
224 - (id)initWithCoder:(CPCoder)coder
225 {
226  self = [super init];
227  if (self != nil)
228  {
229  _predicates = [coder decodeObjectForKey:@"CPCompoundPredicateSubpredicates"];
230  _type = [coder decodeIntForKey:@"CPCompoundPredicateType"];
231  }
232 
233  return self;
234 }
235 
236 - (void)encodeWithCoder:(CPCoder)coder
237 {
238  [coder encodeObject:_predicates forKey:@"CPCompoundPredicateSubpredicates"];
239  [coder encodeInt:_type forKey:@"CPCompoundPredicateType"];
240 }
241 
242 @end
CPCompoundPredicateType compoundPredicateType()
var isEqual
A mutable key-value pair collection.
Definition: CPDictionary.h:2
CPCompoundPredicate is a subclass of CPPredicate used to represent logical “gate” operations (AND/O...
An immutable string (collection of characters).
Definition: CPString.h:2
BOOL evaluateWithObject:substitutionVariables:(id object, [substitutionVariables] CPDictionary variables)
Defines methods for use when archiving & restoring (enc/decoding).
Definition: CPCoder.h:2
id stringWithFormat:(CPString format, [,] ...)
Definition: CPString.j:166