]> err.no Git - sope/blob - sope-core/EOControl/EOValidation.m
removed NGJavaScript support
[sope] / sope-core / EOControl / EOValidation.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "EOClassDescription.h"
24 #include "EOKeyValueCoding.h"
25 #include "EONull.h"
26 #include "common.h"
27
28 #if !LIB_FOUNDATION_LIBRARY
29
30 @interface NSException(UsedSetUI) /* does Jaguar allow -setUserInfo: ? */
31 - (void)setUserInfo:(NSDictionary *)_ui;
32 @end
33
34 #endif
35
36 @implementation NSClassDescription(EOValidation)
37
38 - (NSException *)validateObjectForDelete:(id)_object {
39   return nil;
40 }
41 - (NSException *)validateObjectForSave:(id)_object {
42   return nil;
43 }
44 - (NSException *)validateValue:(id *)_value forKey:(NSString *)_key {
45   return nil;
46 }
47
48 @end /* NSClassDescription(EOValidation) */
49
50 @implementation NSObject(EOValidation)
51
52 - (NSException *)validateForDelete {
53   return [[self classDescription] validateObjectForDelete:self];
54 }
55
56 - (NSException *)validateForInsert {
57   return [self validateForSave];
58 }
59 - (NSException *)validateForUpdate {
60   return [self validateForSave];
61 }
62
63 - (NSException *)validateForSave {
64   NSException    *e;
65   NSMutableArray *exceptions;
66   NSArray        *properties;
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 *);
71   
72   exceptions = nil;
73
74   /* first ask class description to validate object */
75   
76   if ((e = [[self classDescription] validateObjectForSave:self])) {
77     if (exceptions == nil) exceptions = [NSMutableArray array];
78     [exceptions addObject:e];
79   }
80   
81   /* then process all properties */
82   
83   if ((properties = [self allPropertyKeys]) == nil)
84     properties = [NSArray array];
85   
86   validate  = (void *)[self methodForSelector:@selector(validateValue:forKey:)];
87   valForKey = (void *)[self methodForSelector:@selector(valueForKey:)];
88   objAtIdx  = (void *)[properties methodForSelector:@selector(objectAtIndex:)];
89   
90   for (i = 0, count = [properties count]; i < count; i++) {
91     NSString *key;
92     id value, orgValue;
93     
94     key      = objAtIdx(properties, @selector(objectAtIndex:), i);
95     orgValue = value = valForKey(self, @selector(valueForKey:), key);
96     
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];
101     }
102     else if (orgValue != value) {
103       /* the value was changed during validation */
104       [self takeValue:value forKey:key];
105     }
106   }
107   
108   if ((count = [exceptions count]) == 0) {
109     return nil;
110   }
111   else if (count == 1) {
112     return [exceptions objectAtIndex:0];
113   }
114   else {
115     NSException *master;
116     NSMutableDictionary *ui;
117
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;
125     return master;
126   }
127 }
128
129 - (NSException *)validateValue:(id *)_value forKey:(NSString *)_key {
130   NSException *e;
131   
132   if ((e = [[self classDescription] validateValue:_value forKey:_key]))
133     return e;
134   
135   /* should invoke key-specific methods, eg -validateBlah: */
136   
137   {
138     /* construct 'validate'(8) + key + ':'(1) */
139     unsigned len;
140     char *buf;
141     SEL  sel;
142
143     len = [_key cStringLength];
144     buf = malloc(len + 14);
145     strcpy(buf, "validate");
146     [_key getCString:&buf[8]];
147     strcat(buf, ":");
148     buf[8] = toupper(buf[8]);
149     
150 #if NeXT_RUNTIME
151     sel = sel_getUid(buf);
152 #else
153     sel = sel_get_any_uid(buf);
154 #endif
155     if (sel) {
156       if ([self respondsToSelector:sel]) {
157         if (buf) free(buf);
158         return [self performSelector:sel withObject:*_value];
159       }
160     }
161     if (buf) free(buf);
162   }
163   return nil;
164 }
165
166 @end /* NSObject(EOValidation) */