2 Copyright (C) 2000-2005 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 "EOClassDescription.h"
23 #include "EOKeyValueCoding.h"
27 #if !LIB_FOUNDATION_LIBRARY
29 @interface NSException(UsedSetUI) /* does Jaguar allow -setUserInfo: ? */
30 - (void)setUserInfo:(NSDictionary *)_ui;
35 @implementation NSClassDescription(EOValidation)
37 - (NSException *)validateObjectForDelete:(id)_object {
40 - (NSException *)validateObjectForSave:(id)_object {
43 - (NSException *)validateValue:(id *)_value forKey:(NSString *)_key {
47 @end /* NSClassDescription(EOValidation) */
49 @implementation NSObject(EOValidation)
51 - (NSException *)validateForDelete {
52 return [[self classDescription] validateObjectForDelete:self];
55 - (NSException *)validateForInsert {
56 return [self validateForSave];
58 - (NSException *)validateForUpdate {
59 return [self validateForSave];
62 - (NSException *)validateForSave {
64 NSMutableArray *exceptions;
66 unsigned int i, count;
67 id (*validate)(id, SEL, id *, NSString *);
68 id (*objAtIdx)(id, SEL, unsigned int idx);
69 id (*valForKey)(id, SEL, NSString *);
73 /* first ask class description to validate object */
75 if ((e = [[self classDescription] validateObjectForSave:self])) {
76 if (exceptions == nil) exceptions = [NSMutableArray array];
77 [exceptions addObject:e];
80 /* then process all properties */
82 if ((properties = [self allPropertyKeys]) == nil)
83 properties = [NSArray array];
85 validate = (void *)[self methodForSelector:@selector(validateValue:forKey:)];
86 valForKey = (void *)[self methodForSelector:@selector(valueForKey:)];
87 objAtIdx = (void *)[properties methodForSelector:@selector(objectAtIndex:)];
89 for (i = 0, count = [properties count]; i < count; i++) {
93 key = objAtIdx(properties, @selector(objectAtIndex:), i);
94 orgValue = value = valForKey(self, @selector(valueForKey:), key);
96 if ((e = validate(self, @selector(validateValue:forKey:), &value, key))) {
97 /* validation of property failed */
98 if (exceptions == nil) exceptions = [NSMutableArray array];
99 [exceptions addObject:e];
101 else if (orgValue != value) {
102 /* the value was changed during validation */
103 [self takeValue:value forKey:key];
107 if ((count = [exceptions count]) == 0) {
110 else if (count == 1) {
111 return [exceptions objectAtIndex:0];
115 NSMutableDictionary *ui;
117 master = [exceptions objectAtIndex:0];
118 [exceptions removeObjectAtIndex:0];
119 ui = [[master userInfo] mutableCopy];
120 if (ui == nil) ui = [[NSMutableDictionary alloc] init];
121 [ui setObject:exceptions forKey:@"EOAdditionalExceptions"];
122 [master setUserInfo:ui];
123 [ui release]; ui = nil;
128 - (NSException *)validateValue:(id *)_value forKey:(NSString *)_key {
131 if ((e = [[self classDescription] validateValue:_value forKey:_key]))
134 /* should invoke key-specific methods, eg -validateBlah: */
137 /* construct 'validate'(8) + key + ':'(1) */
142 len = [_key cStringLength];
143 buf = malloc(len + 14);
144 strcpy(buf, "validate");
145 [_key getCString:&buf[8]];
147 buf[8] = toupper(buf[8]);
150 sel = sel_getUid(buf);
152 sel = sel_get_any_uid(buf);
155 if ([self respondsToSelector:sel]) {
157 return [self performSelector:sel withObject:*_value];
165 @end /* NSObject(EOValidation) */