![]() |
API 0.9.5
|
00001 /* 00002 * CPCompoundPredicate.j 00003 * 00004 * Portions based on NSCompoundPredicate.m in Cocotron (http://www.cocotron.org/) 00005 * Copyright (c) 2006-2007 Christopher J. W. Lloyd 00006 * 00007 * Created by cacaodev. 00008 * Copyright 2010. 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00023 */ 00024 00025 00031 CPNotPredicateType = 0; 00037 CPAndPredicateType = 1; 00043 CPOrPredicateType = 2; 00044 00045 var CPCompoundPredicateType; 00046 00056 @implementation CPCompoundPredicate : CPPredicate 00057 { 00058 CPCompoundPredicateType _type; 00059 CPArray _predicates; 00060 } 00061 00062 // Constructors 00068 - (id)initWithType:(CPCompoundPredicateType)type subpredicates:(CPArray)predicates 00069 { 00070 self = [super init]; 00071 00072 if (self) 00073 { 00074 _type = type; 00075 _predicates = predicates; 00076 } 00077 00078 return self; 00079 } 00080 00086 + (CPPredicate)notPredicateWithSubpredicate:(CPPredicate)predicate 00087 { 00088 return [[self alloc] initWithType:CPNotPredicateType subpredicates:[CPArray arrayWithObject:predicate]]; 00089 } 00090 00096 + (CPPredicate)andPredicateWithSubpredicates:(CPArray)subpredicates 00097 { 00098 return [[self alloc] initWithType:CPAndPredicateType subpredicates:subpredicates]; 00099 } 00100 00106 + (CPPredicate)orPredicateWithSubpredicates:(CPArray)predicates 00107 { 00108 return [[self alloc] initWithType:CPOrPredicateType subpredicates:predicates]; 00109 } 00110 00111 // Getting Information About a Compound Predicate 00116 - (CPCompoundPredicateType)compoundPredicateType 00117 { 00118 return _type; 00119 } 00120 00125 - (CPArray)subpredicates 00126 { 00127 return _predicates; 00128 } 00129 00130 - (CPPredicate)predicateWithSubstitutionVariables:(CPDictionary)variables 00131 { 00132 var subp = [CPArray array], 00133 count = [subp count], 00134 i = 0; 00135 00136 for (; i < count; i++) 00137 { 00138 var p = [subp objectAtIndex:i], 00139 sp = [p predicateWithSubstitutionVariables:variables]; 00140 00141 [subp addObject:sp]; 00142 } 00143 00144 return [[CPCompoundPredicate alloc] initWithType:_type subpredicates:subp]; 00145 } 00146 00147 - (CPString)predicateFormat 00148 { 00149 var result = "", 00150 args = [CPArray array], 00151 count = [_predicates count], 00152 i = 0; 00153 00154 if (count == 0) 00155 return @"TRUPREDICATE"; 00156 00157 for (; i < count; i++) 00158 { 00159 var subpredicate = [_predicates objectAtIndex:i], 00160 precedence = [subpredicate predicateFormat]; 00161 00162 if ([subpredicate isKindOfClass:[CPCompoundPredicate class]] && [[subpredicate subpredicates] count]> 1 && [subpredicate compoundPredicateType] != _type) 00163 precedence = [CPString stringWithFormat:@"(%s)",precedence]; 00164 00165 if (precedence != nil) 00166 [args addObject:precedence]; 00167 } 00168 00169 switch (_type) 00170 { 00171 case CPNotPredicateType: result += "NOT %s" + [args objectAtIndex:0]; 00172 break; 00173 00174 case CPAndPredicateType: result += [args objectAtIndex:0]; 00175 var count = [args count]; 00176 for (var j = 1; j < count; j++) 00177 result += " AND " + [args objectAtIndex:j]; 00178 break; 00179 00180 case CPOrPredicateType: result += [args objectAtIndex:0]; 00181 var count = [args count]; 00182 for (var j = 1; j < count; j++) 00183 result += " OR " + [args objectAtIndex:j]; 00184 break; 00185 } 00186 00187 return result; 00188 } 00189 00190 - (BOOL)evaluateWithObject:(id)object 00191 { 00192 return [self evaluateWithObject:object substitutionVariables:nil]; 00193 } 00194 00195 - (BOOL)evaluateWithObject:(id)object substitutionVariables:(CPDictionary)variables 00196 { 00197 var result = NO, 00198 count = [_predicates count], 00199 i = 0; 00200 00201 if (count == 0) 00202 return YES; 00203 00204 for (; i < count; i++) 00205 { 00206 var predicate = [_predicates objectAtIndex:i]; 00207 00208 switch (_type) 00209 { 00210 case CPNotPredicateType: return ![predicate evaluateWithObject:object substitutionVariables:variables]; 00211 00212 case CPAndPredicateType: if (i == 0) 00213 result = [predicate evaluateWithObject:object substitutionVariables:variables]; 00214 else 00215 result = result && [predicate evaluateWithObject:object substitutionVariables:variables]; 00216 if (!result) 00217 return NO; 00218 break; 00219 00220 case CPOrPredicateType: if ([predicate evaluateWithObject:object substitutionVariables:variables]) 00221 return YES; 00222 break; 00223 } 00224 } 00225 00226 return result; 00227 } 00228 00229 @end 00230 00231 @implementation CPCompoundPredicate (CPCoding) 00232 00233 - (id)initWithCoder:(CPCoder)coder 00234 { 00235 self = [super init]; 00236 if (self != nil) 00237 { 00238 _predicates = [coder decodeObjectForKey:@"CPCompoundPredicateSubpredicates"]; 00239 _type = [coder decodeIntForKey:@"CPCompoundPredicateType"]; 00240 } 00241 00242 return self; 00243 } 00244 00245 - (void)encodeWithCoder:(CPCoder)coder 00246 { 00247 [coder encodeObject:_predicates forKey:@"CPCompoundPredicateSubpredicates"]; 00248 [coder encodeInt:_type forKey:@"CPCompoundPredicateType"]; 00249 } 00250 00251 @end