2 Copyright (C) 2003-2004 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include "NGRuleModel.h"
24 #include "NGRuleParser.h"
25 #include "EOTrueQualifier.h"
26 #include <NGExtensions/NSObject+Logs.h>
27 #import <EOControl/EOControl.h>
30 // TODO: add a candidate cache
32 @implementation NGRuleModel
34 + (id)ruleModelWithPropertyList:(id)_plist {
35 static NGRuleParser *ruleParser = nil; // THREAD
37 if (ruleParser == nil)
38 ruleParser = [[NGRuleParser sharedRuleParser] retain];
40 return [ruleParser parseRuleModelFromPropertyList:_plist];
42 + (id)ruleModelWithContentsOfUserDefault:(NSString *)_defName {
45 plist = [[NSUserDefaults standardUserDefaults] objectForKey:_defName];
46 if (plist == nil) return nil;
48 return [self ruleModelWithPropertyList:plist];
52 if ((self = [super init])) {
53 self->rules = [[NSMutableArray alloc] initWithCapacity:16];
57 - (id)initWithRules:(NSArray *)_rules {
58 if ((self = [self init])) {
59 [self->rules addObjectsFromArray:_rules];
64 - (id)initWithPropertyList:(id)_plist {
66 return [[[self class] ruleModelWithPropertyList:_plist] retain];
69 - (id)initWithContentsOfFile:(NSString *)_path {
73 if ((s = [[NSString alloc] initWithContentsOfFile:_path])) {
77 plist = [s propertyList];
79 return [self initWithPropertyList:plist];
82 - (id)initWithContentsOfUserDefault:(NSString *)_defName {
84 return [[[self class] ruleModelWithContentsOfUserDefault:_defName] retain];
87 - (id)initWithKeyValueArchiveAtURL:(NSURL *)_url {
88 EOKeyValueUnarchiver *unarchiver;
91 if ((plist = [NSDictionary dictionaryWithContentsOfURL:_url]) == nil) {
92 [self errorWithFormat:@"Could not read plist at URL: %@", _url];
97 unarchiver = [[EOKeyValueUnarchiver alloc] initWithDictionary:plist];
98 self = [self initWithKeyValueUnarchiver:unarchiver];
99 [unarchiver release]; unarchiver = nil;
105 [self->rules release];
111 - (void)setRules:(NSArray *)_rules {
112 [self->rules removeAllObjects];
113 if (_rules != nil) [self->rules addObjectsFromArray:_rules];
116 return [[self->rules shallowCopy] autorelease];
119 - (void)addRule:(NGRule *)_rule {
120 if (_rule == nil) return;
121 [self->rules addObject:_rule];
123 - (void)removeRule:(NGRule *)_rule {
124 if (_rule == nil) return;
125 [self->rules removeObject:_rule];
128 - (void)addRules:(NSArray *)_rules {
129 if (_rules != nil) [self->rules addObjectsFromArray:_rules];
134 static int candidateSort(NGRule *rule1, NGRule *rule2, NGRuleModel *model) {
135 static Class TrueQualClass = Nil;
136 EOQualifier *q1, *q2;
137 register int pri1, pri2;
139 pri1 = [rule1 priority];
140 pri2 = [rule2 priority];
142 return pri1 > pri2 ? NSOrderedAscending : NSOrderedDescending;
144 /* check number of qualifiers (order on how specific the qualifier is) */
146 if (TrueQualClass == Nil) TrueQualClass = [EOTrueQualifier class];
147 q1 = [rule1 qualifier];
148 q2 = [rule2 qualifier];
150 pri1 = [q1 isKindOfClass:TrueQualClass]
152 : ([q1 respondsToSelector:@selector(count)] ? [q1 count] : 0);
153 pri2 = [q2 isKindOfClass:TrueQualClass]
155 : ([q2 respondsToSelector:@selector(count)] ? [q2 count] : 0);
158 return pri1 > pri2 ? NSOrderedAscending : NSOrderedDescending;
160 return NSOrderedSame;
163 - (NSArray *)candidateRulesForKey:(NSString *)_key {
164 NSMutableArray *candidates;
167 /* first, find all candidates */
169 cnt = [self->rules count];
170 for (i = 0; i < cnt; i++) {
173 rule = [self->rules objectAtIndex:i];
174 if ([rule isCandidateForKey:_key]) {
175 if (candidates == nil)
176 candidates = [[NSMutableArray alloc] initWithCapacity:cnt];
177 [candidates addObject:rule];
181 /* sort candidates */
182 [candidates sortUsingFunction:(void *)candidateSort context:self];
187 /* representations */
189 /* key/value archiving */
191 - (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
192 return [self initWithRules:[_unarchiver decodeObjectForKey:@"rules"]];
194 - (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver {
195 [_archiver encodeObject:[self rules] forKey:@"rules"];
198 @end /* NGRuleModel */