2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo 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 OGo 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 OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "EOClassDescription.h"
24 #include "EOKeyValueCoding.h"
28 #if !LIB_FOUNDATION_LIBRARY
30 @interface NSException(UsedSetUI) /* does Jaguar allow -setUserInfo: ? */
31 - (void)setUserInfo:(NSDictionary *)_ui;
36 @implementation NSClassDescription(EOValidation)
38 - (NSException *)validateObjectForDelete:(id)_object {
41 - (NSException *)validateObjectForSave:(id)_object {
44 - (NSException *)validateValue:(id *)_value forKey:(NSString *)_key {
48 @end /* NSClassDescription(EOValidation) */
50 @implementation NSObject(EOValidation)
52 - (NSException *)validateForDelete {
53 return [[self classDescription] validateObjectForDelete:self];
56 - (NSException *)validateForInsert {
57 return [self validateForSave];
59 - (NSException *)validateForUpdate {
60 return [self validateForSave];
63 - (NSException *)validateForSave {
65 NSMutableArray *exceptions;
67 unsigned int i, count;
68 id (*validate)(id, SEL, id *, NSString *);
69 id (*objAtIdx)(id, SEL, unsigned int idx);
70 id (*valForKey)(id, SEL, NSString *);
74 /* first ask class description to validate object */
76 if ((e = [[self classDescription] validateObjectForSave:self])) {
77 if (exceptions == nil) exceptions = [NSMutableArray array];
78 [exceptions addObject:e];
81 /* then process all properties */
83 if ((properties = [self allPropertyKeys]) == nil)
84 properties = [NSArray array];
86 validate = (void *)[self methodForSelector:@selector(validateValue:forKey:)];
87 valForKey = (void *)[self methodForSelector:@selector(valueForKey:)];
88 objAtIdx = (void *)[properties methodForSelector:@selector(objectAtIndex:)];
90 for (i = 0, count = [properties count]; i < count; i++) {
94 key = objAtIdx(properties, @selector(objectAtIndex:), i);
95 orgValue = value = valForKey(self, @selector(valueForKey:), key);
97 if ((e = validate(self, @selector(validateValue:forKey:), &value, key))) {
98 /* validation of property failed */
99 if (exceptions == nil) exceptions = [NSMutableArray array];
100 [exceptions addObject:e];
102 else if (orgValue != value) {
103 /* the value was changed during validation */
104 [self takeValue:value forKey:key];
108 if ((count = [exceptions count]) == 0) {
111 else if (count == 1) {
112 return [exceptions objectAtIndex:0];
116 NSMutableDictionary *ui;
118 master = [exceptions objectAtIndex:0];
119 [exceptions removeObjectAtIndex:0];
120 ui = [[master userInfo] mutableCopy];
121 if (ui == nil) ui = [[NSMutableDictionary alloc] init];
122 [ui setObject:exceptions forKey:@"EOAdditionalExceptions"];
123 [master setUserInfo:ui];
124 [ui release]; ui = nil;
129 - (NSException *)validateValue:(id *)_value forKey:(NSString *)_key {
132 if ((e = [[self classDescription] validateValue:_value forKey:_key]))
135 /* should invoke key-specific methods, eg -validateBlah: */
138 /* construct 'validate'(8) + key + ':'(1) */
143 len = [_key cStringLength];
144 buf = malloc(len + 14);
145 strcpy(buf, "validate");
146 [_key getCString:&buf[8]];
148 buf[8] = toupper(buf[8]);
151 sel = sel_getUid(buf);
153 sel = sel_get_any_uid(buf);
156 if ([self respondsToSelector:sel]) {
158 return [self performSelector:sel withObject:*_value];
166 @end /* NSObject(EOValidation) */