2 Copyright (C) 2003-2006 SKYRIX Software AG
3 Copyright (C) 2006 Helge Hess
5 This file is part of SOPE.
7 SOPE is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with SOPE; see the file COPYING. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "NGRuleContext.h"
25 #include "NGRuleModel.h"
26 #include "NSObject+Logs.h"
28 #import <EOControl/EOQualifier.h>
30 @implementation NGRuleContext
32 + (id)ruleContextWithModelInUserDefault:(NSString *)_defName {
35 if ((mod = [NGRuleModel ruleModelWithContentsOfUserDefault:_defName]) == nil)
38 return [self ruleContextWithModel:mod];
41 + (id)ruleContextWithModel:(NGRuleModel *)_model {
42 return [[[self alloc] initWithModel:_model] autorelease];
45 - (id)initWithModel:(NGRuleModel *)_model {
46 if ((self = [super init])) {
47 [self setModel:_model];
52 return [self initWithModel:nil];
56 [self->model release];
57 [self->storedValues release];
63 - (void)setModel:(NGRuleModel *)_model {
64 ASSIGN(self->model, _model);
66 - (NGRuleModel *)model {
72 - (void)takeStoredValue:(id)_value forKey:(NSString *)_key {
74 if (self->storedValues == nil)
75 self->storedValues = [[NSMutableDictionary alloc] initWithCapacity:32];
76 [self->storedValues setObject:_value forKey:_key];
79 [self->storedValues removeObjectForKey:_key];
81 - (id)storedValueForKey:(NSString *)_key {
82 return [self->storedValues objectForKey:_key];
85 - (void)takeValue:(id)_value forKey:(NSString *)_key {
86 [self takeStoredValue:_value forKey:_key];
90 [self->storedValues removeAllObjects];
95 - (id)inferredValueForKey:(NSString *)_key {
100 [self debugWithFormat:@"calculate value for key: '%@'", _key];
102 /* select candidates */
103 rules = [[self model] candidateRulesForKey:_key];
105 [self debugWithFormat:@" candidate rules: %@", rules];
107 /* check qualifiers */
108 for (i = 0, count = [rules count]; i < count; i++) {
111 rule = [rules objectAtIndex:i];
112 if ([(id<EOQualifierEvaluation>)[rule qualifier] evaluateWithObject:self]){
114 [self debugWithFormat:@" rule %i matches: %@", i, rule];
115 return [[rule action] fireInContext:self];
119 [self debugWithFormat:@" no rule matched !"];
123 - (NSArray *)allPossibleValuesForKey:(NSString *)_key {
124 NSMutableArray *values;
129 [self debugWithFormat:@"calculate all values for key: '%@'", _key];
131 /* select candidates */
132 rules = [[self model] candidateRulesForKey:_key];
134 [self debugWithFormat:@" candidate rules: %@", rules];
136 values = [NSMutableArray arrayWithCapacity:16];
138 /* check qualifiers */
139 for (i = 0, count = [rules count]; i < count; i++) {
142 rule = [rules objectAtIndex:i];
143 if ([(id<EOQualifierEvaluation>)[rule qualifier] evaluateWithObject:self]){
147 [self debugWithFormat:@" rule %i matches: %@", i, rule];
149 v = [[rule action] fireInContext:self];
150 [values addObject:(v != nil ? v : (id)[NSNull null])];
154 [self debugWithFormat:@" %d rules matched.", [values count]];
158 - (id)valueForKey:(NSString *)_key {
161 // TODO: add rule cache?
163 /* look for constants */
164 if ((v = [self->storedValues objectForKey:_key]) != nil)
167 /* look into rule system */
168 if ((v = [self inferredValueForKey:_key]) != nil)
174 - (NSArray *)valuesForKeyPath:(NSString *)_kp
175 takingSuccessiveValues:(NSArray *)_values
176 forKeyPath:(NSString *)_valkp
178 NSMutableArray *results;
181 count = [_values count];
182 results = [NSMutableArray arrayWithCapacity:count];
184 for (i = 0; i < count; i++) {
188 [self takeValue:[_values objectAtIndex:i] forKeyPath:_valkp];
190 /* calculate the rule value */
191 ruleValue = [self valueForKeyPath:_kp];
192 [results addObject:(ruleValue != nil ? ruleValue : (id)[NSNull null])];
199 - (BOOL)isDebuggingEnabled {
200 return self->debugOn;
202 - (void)setDebugEnabled:(BOOL)_flag {
203 self->debugOn = _flag;
206 @end /* NGRuleContext */