API 0.9.5
Foundation/CPPredicate/CPCompoundPredicate.j
Go to the documentation of this file.
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
 All Classes Files Functions Variables Defines