]> err.no Git - sope/blob - sope-gdl1/GDLAccess/EOEntityClassDescription.m
added missing inline pathes
[sope] / sope-gdl1 / GDLAccess / EOEntityClassDescription.m
1 /* 
2    EOAttributeOrdering.m
3
4    Copyright (C) 1996 Free Software Foundation, Inc.
5
6    Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
7    Date: 1996
8
9    This file is part of the GNUstep Database Library.
10
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Library General Public
13    License as published by the Free Software Foundation; either
14    version 2 of the License, or (at your option) any later version.
15
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Library General Public License for more details.
20
21    You should have received a copy of the GNU Library General Public
22    License along with this library; see the file COPYING.LIB.
23    If not, write to the Free Software Foundation,
24    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27 // $Id: EOEntityClassDescription.m 1 2004-08-20 10:38:46Z znek $
28
29 #import "common.h"
30 #import "EOEntity.h"
31 #import "EOAttribute.h"
32 #import "EORelationship.h"
33 #import <EOControl/EOKeyValueCoding.h>
34 #import <EOControl/EOKeyGlobalID.h>
35
36 @interface EOClassDescription(ClassDesc)
37 /* TODO: check, whether this can be removed */
38 + (NSClassDescription *)classDescriptionForEntityName:(NSString *)_entityName;
39 @end
40
41 @implementation EOEntityClassDescription
42
43 - (id)initWithEntity:(EOEntity *)_entity {
44   self->entity = RETAIN(_entity);
45   return self;
46 }
47
48 - (void)dealloc {
49   RELEASE(self->entity);
50   [super dealloc];
51 }
52
53 /* creating instances */
54
55 - (id)createInstanceWithEditingContext:(id)_ec
56   globalID:(EOGlobalID *)_oid
57   zone:(NSZone *)_zone
58 {
59   Class eoClass;
60   id eo;
61   
62   eoClass = NSClassFromString([self->entity className]);
63   eo = [eoClass allocWithZone:_zone];
64   
65   if ([eo respondsToSelector:
66           @selector(initWithEditingContext:classDescription:globalID:)])
67     eo = [eo initWithEditingContext:_ec classDescription:self globalID:_oid];
68   else
69     eo = [eo init];
70
71   return AUTORELEASE(eo);
72 }
73
74 /* accessors */
75
76 - (EOEntity *)entity {
77   return self->entity;
78 }
79
80 /* model */
81
82 - (NSString *)entityName {
83   return [self->entity name];
84 }
85
86 - (NSArray *)attributeKeys {
87   NSArray      *attrs    = [self->entity attributes];
88   unsigned int attrCount = [attrs count];
89   id           keys[attrCount];
90   unsigned int i;
91
92   for (i = 0; i < attrCount; i++) {
93     EOAttribute *attribute;
94
95     attribute = [attrs objectAtIndex:i];
96     keys[i] = [attribute name];
97   }
98
99   return [NSArray arrayWithObjects:keys count:attrCount];
100 }
101
102 - (NSArray *)toManyRelationshipKeys {
103   NSArray      *relships = [self->entity relationships];
104   unsigned int attrCount = [relships count];
105   id           keys[attrCount];
106   unsigned int i, j;
107
108   for (i = 0, j = 0; i < attrCount; i++) {
109     EORelationship *relship;
110
111     relship = [relships objectAtIndex:i];
112     if ([relship isToMany]) {
113       keys[j] = [relship name];
114     }
115   }
116   return [NSArray arrayWithObjects:keys count:j];
117 }
118
119 - (NSArray *)toOneRelationshipKeys {
120   NSArray      *relships = [self->entity relationships];
121   unsigned int attrCount = [relships count];
122   id           keys[attrCount];
123   unsigned int i, j;
124
125   for (i = 0, j = 0; i < attrCount; i++) {
126     EORelationship *relship;
127
128     relship = [relships objectAtIndex:i];
129     if (![relship isToMany]) {
130       keys[j] = [relship name];
131     }
132   }
133   return [NSArray arrayWithObjects:keys count:j];
134 }
135
136
137 - (NSClassDescription *)classDescriptionForDestinationKey:(NSString *)_key {
138   /* TODO: is this used anywhere?, maybe remove? */
139   EORelationship *relship;
140   NSString       *targetEntityName;
141   
142   if ((relship = [self->entity relationshipNamed:_key]) == nil)
143     return nil;
144   
145   if ([relship isToMany])
146     return nil;
147   
148   targetEntityName = [[relship entity] name];
149   
150   return [EOClassDescription classDescriptionForEntityName:targetEntityName];
151 }
152
153 /* validation */
154
155 - (NSException *)validateObjectForSave:(id)_object {
156   NSMutableArray *exceptions;
157   NSArray        *attrs;
158   unsigned int   count, i;
159
160   exceptions = nil;
161   
162   /* validate attributes */
163   
164   attrs = [self->entity attributes];
165   count = [attrs count];
166   
167   for (i = 0; i < count; i++) {
168     EOAttribute *attribute;
169     NSException *exception;
170     id oldValue, newValue;
171     
172     attribute = [attrs objectAtIndex:i];
173     oldValue  = [_object storedValueForKey:[attribute name]];
174     newValue  = oldValue;
175     
176     if ((exception = [attribute validateValue:&newValue])) {
177       /* validation failed */
178       if (exceptions == nil) exceptions = [NSMutableArray array];
179       [exceptions addObject:exception];
180     }
181     else if (oldValue != newValue) {
182       /* apply new value to object (value was changed by val-method) */
183       [_object takeStoredValue:newValue forKey:[attribute name]];
184     }
185   }
186
187   /* validate relationships */
188
189   attrs = [self->entity relationships];
190   count = [attrs count];
191   
192   for (i = 0; i < count; i++) {
193     EORelationship *relationship;
194     NSException *exception;
195     id oldValue, newValue;
196     
197     relationship = [attrs objectAtIndex:i];
198     oldValue     = [_object storedValueForKey:[relationship name]];
199     newValue     = oldValue;
200     
201     if ((exception = [relationship validateValue:&newValue])) {
202       /* validation failed */
203       if (exceptions == nil) exceptions = [NSMutableArray array];
204       [exceptions addObject:exception];
205     }
206     else if (oldValue != newValue) {
207       /* apply new value to object (value was changed by val-method) */
208       [_object takeStoredValue:newValue forKey:[relationship name]];
209     }
210   }
211   
212   /* process exceptions */
213   
214   if ((count = [exceptions count]) == 0)
215     return nil;
216
217   if (count == 1)
218     return [exceptions objectAtIndex:0];
219   
220   {
221     NSException *master;
222     NSMutableDictionary *ui;
223     
224     master = [exceptions objectAtIndex:0];
225     ui = [[master userInfo] mutableCopy];
226     if (ui == nil) ui = [[NSMutableDictionary alloc] init];
227     [ui setObject:exceptions forKey:@"EOAdditionalExceptions"];
228     
229     master = [NSException exceptionWithName:[master name]
230                           reason:[master reason]
231                           userInfo:ui];
232     [ui release]; ui = nil;
233     return master;
234   }
235 }
236
237 @end /* EOEntityClassDescription */