GNUstep Core Data
0.1
|
00001 /* Implementation of the NSEntityDescription class for the GNUstep 00002 Core Data framework. 00003 Copyright (C) 2005 Free Software Foundation, Inc. 00004 00005 Written by: Saso Kiselkov <diablos@manga.sk> 00006 Date: August 2005 00007 00008 This file is part of the GNUstep Core Data framework. 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2.1 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this library; if not, write to the Free 00022 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. 00023 */ 00024 00025 #import "CoreDataHeaders.h" 00026 00027 // Ensures the entity can be edited. Raises an NSGenericException 00028 // if the passed model is not nil and is not editable, with a reason 00029 // set to `reason'. 00030 static inline void EnsureEntityEditable(NSManagedObjectModel * model, 00031 NSString * reason) 00032 { 00033 if (model != nil && [model _isEditable] == NO) 00034 { 00035 [NSException raise: NSGenericException format: reason]; 00036 } 00037 } 00038 00039 00040 @implementation NSEntityDescription 00041 00042 00043 - (NSDictionary *) _filteredPropertiesOfClass: (Class) aClass 00044 { 00045 NSMutableDictionary * dict; 00046 NSEnumerator * e; 00047 NSPropertyDescription * property; 00048 00049 dict = [NSMutableDictionary dictionaryWithCapacity: [_properties count]]; 00050 e = [_properties objectEnumerator]; 00051 while ((property = [e nextObject]) != nil) 00052 { 00053 if (aClass == Nil || [property isKindOfClass: aClass]) 00054 { 00055 [dict setObject: property forKey: [property name]]; 00056 } 00057 } 00058 00059 return [[dict copy] autorelease]; 00060 } 00061 00062 - (NSDictionary *) _fetchedPropertiesByName 00063 { 00064 return [self _filteredPropertiesOfClass: [NSFetchedPropertyDescription 00065 class]]; 00066 } 00067 00068 + (NSEntityDescription *) entityForName: (NSString *) entityName 00069 inManagedObjectContext: (NSManagedObjectContext *) ctxt 00070 { 00071 return [[[[ctxt persistentStoreCoordinator] managedObjectModel] 00072 entitiesByName] objectForKey: entityName]; 00073 } 00074 00075 + (id) insertNewObjectForEntityForName: (NSString *) anEntityName 00076 inManagedObjectContext: (NSManagedObjectContext *) aContext 00077 { 00078 NSEntityDescription * entity; 00079 Class entityClass; 00080 NSManagedObjectModel * model; 00081 00082 model = [[aContext persistentStoreCoordinator] managedObjectModel]; 00083 entity = [[model entitiesByName] objectForKey: anEntityName]; 00084 00085 entityClass = NSClassFromString([entity managedObjectClassName]); 00086 00087 return [[[entityClass alloc] 00088 initWithEntity: entity insertIntoManagedObjectContext: aContext] 00089 autorelease]; 00090 } 00091 00092 - (void) dealloc 00093 { 00094 TEST_RELEASE(_name); 00095 00096 // let go of our properties 00097 [_properties makeObjectsPerformSelector: @selector(_setEntity:) 00098 withObject: nil]; 00099 TEST_RELEASE(_properties); 00100 00101 TEST_RELEASE(_userInfo); 00102 TEST_RELEASE(_managedObjectClassName); 00103 00104 [_subentities makeObjectsPerformSelector: @selector(setSuperentity:) 00105 withObject: nil]; 00106 00107 TEST_RELEASE(_subentities); 00108 00109 [super dealloc]; 00110 } 00111 00112 00113 00114 - (NSString *) name 00115 { 00116 return _name; 00117 } 00118 00119 - (void) setName: (NSString *) aName 00120 { 00121 EnsureEntityEditable(_model, _(@"Tried to set the name of an " 00122 @"entity alredy in use.")); 00123 ASSIGN(_name, aName); 00124 } 00125 00126 00127 00128 - (NSManagedObjectModel *) managedObjectModel 00129 { 00130 return _model; 00131 } 00132 00133 00134 00135 - (NSString *) managedObjectClassName 00136 { 00137 return _managedObjectClassName; 00138 } 00139 00140 - (void) setManagedObjectClassName: (NSString *) aName 00141 { 00142 EnsureEntityEditable(_model, _(@"Tried to set the managed object " 00143 @"class name of an entity already in use")); 00144 ASSIGN(_managedObjectClassName, aName); 00145 } 00146 00147 00148 00149 - (BOOL) isAbstract 00150 { 00151 return _abstract; 00152 } 00153 00154 - (void) setAbstract: (BOOL) flag 00155 { 00156 EnsureEntityEditable(_model, _(@"Tried to set abstractness " 00157 @"of an entity already in use")); 00158 _abstract = flag; 00159 } 00160 00165 - (BOOL) _isSubentityOfEntity: (NSEntityDescription *) otherEntity 00166 { 00167 NSEntityDescription * entity; 00168 00169 for (entity = self; entity != nil; entity = [entity superentity]) 00170 { 00171 if ([entity isEqual: otherEntity]) 00172 { 00173 return YES; 00174 } 00175 } 00176 00177 return NO; 00178 } 00179 00180 - (NSDictionary *) subentitiesByName 00181 { 00182 NSMutableDictionary * dict; 00183 NSEnumerator * e; 00184 NSEntityDescription * subentity; 00185 00186 dict = [NSMutableDictionary dictionaryWithCapacity: [_subentities count]]; 00187 e = [_subentities objectEnumerator]; 00188 while ((subentity = [e nextObject]) != nil) 00189 { 00190 [dict setObject: subentity forKey: [subentity name]]; 00191 } 00192 00193 return [[dict copy] autorelease]; 00194 } 00195 00196 - (NSArray *) subentities 00197 { 00198 return _subentities; 00199 } 00200 00201 - (void) setSubentities: (NSArray *) someEntities 00202 { 00203 EnsureEntityEditable(_model, _(@"Tried to set sub-entities of an entity " 00204 @"already in use")); 00205 ASSIGN(_subentities, [[someEntities copy] autorelease]); 00206 } 00207 00208 00209 - (NSEntityDescription *) superentity 00210 { 00211 return _superentity; 00212 } 00213 00214 - (void) _setSuperentity: (NSEntityDescription *) entity 00215 { 00216 EnsureEntityEditable(_model, _(@"Tried to set super-entity of an entity " 00217 @"already in use")); 00218 _superentity = entity; 00219 } 00220 00221 00222 00223 - (NSDictionary *) propertiesByName 00224 { 00225 return [self filteredPropertiesOfClass: Nil]; 00226 } 00227 00228 - (NSArray *) properties 00229 { 00230 return _properties; 00231 } 00232 00233 - (void) setProperties: (NSArray *) someProperties 00234 { 00235 EnsureEntityEditable(_model, _(@"Tried to set properties " 00236 @"of an entity already in use")); 00237 ASSIGN(_properties, [[someProperties copy] autorelease]); 00238 [_properties makeObjectsPerformSelector: @selector(_setEntity:) 00239 withObject: self]; 00240 } 00241 00242 - (NSDictionary *) userInfo 00243 { 00244 return _userInfo; 00245 } 00246 00247 - (void) setUserInfo: (NSDictionary *) userInfo 00248 { 00249 EnsureEntityEditable(_model, _(@"Tried to set properties " 00250 @"of an entity already in use")); 00251 ASSIGN(_userInfo, [[userInfo copy] autorelease]); 00252 } 00253 00254 00255 00256 - (NSDictionary *) attributesByName 00257 { 00258 return [self _filteredPropertiesOfClass: [NSAttributeDescription class]]; 00259 } 00260 00261 - (NSDictionary *) relationshipsByName 00262 { 00263 return [self _filteredPropertiesOfClass: [NSRelationshipDescription class]]; 00264 } 00265 00266 - (NSArray *) relationshipsWithDestinationEntity: 00267 (NSEntityDescription *) destEntity 00268 { 00269 NSMutableArray * array; 00270 NSEnumerator * e; 00271 NSRelationshipDescription * relationship; 00272 Class relationshipClass; 00273 00274 array = [NSMutableArray arrayWithCapacity: [_properties count]]; 00275 relationshipClass = [NSRelationshipDescription class]; 00276 00277 e = [_properties objectEnumerator]; 00278 while ((relationship = [e nextObject]) != nil) 00279 { 00280 if ([relationship isKindOfClass: relationshipClass] && 00281 [relationship destinationEntity] == destEntity) 00282 { 00283 [array addObject: relationship]; 00284 } 00285 } 00286 00287 return [[array copy] autorelease]; 00288 } 00289 00290 // NSCopying 00291 00292 - (id) copyWithZone: (NSZone *) aZone 00293 { 00294 NSEntityDescription * entity; 00295 00296 entity = [[NSEntityDescription allocWithZone: aZone] init]; 00297 00298 [entity setName: _name]; 00299 [entity setManagedObjectClassName: _managedObjectClassName]; 00300 [entity setAbstract: _abstract]; 00301 [entity setSubentities: _subentities]; 00302 [entity _setSuperentity: _superentity]; 00303 00304 return entity; 00305 } 00306 00307 // NSCoding 00308 00309 - (id) initWithCoder: (NSCoder *) coder 00310 { 00311 if ((self = [self init])) 00312 { 00313 if ([coder allowsKeyedCoding]) 00314 { 00315 ASSIGN(_name, [coder decodeObjectForKey: @"Name"]); 00316 _abstract = [coder decodeBoolForKey: @"Abstract"]; 00317 ASSIGN(_managedObjectClassName, 00318 [coder decodeObjectForKey: @"ManagedObjectClassName"]); 00319 ASSIGN(_properties, [coder decodeObjectForKey: @"Properties"]); 00320 ASSIGN(_userInfo, [coder decodeObjectForKey: @"UserInfo"]); 00321 ASSIGN(_subentities, [coder decodeObjectForKey: @"SubEntities"]); 00322 _superentity = [coder decodeObjectForKey: @"SuperEntity"]; 00323 _model = [coder decodeObjectForKey: @"ManagedObjectModel"]; 00324 _modelRefCount = [coder decodeIntForKey: @"ModelReferenceCount"]; 00325 } 00326 else 00327 { 00328 ASSIGN(_name, [coder decodeObject]); 00329 [coder decodeValueOfObjCType: @encode(BOOL) at: &_abstract]; 00330 ASSIGN(_managedObjectClassName, [coder decodeObject]); 00331 ASSIGN(_properties, [coder decodeObject]); 00332 ASSIGN(_userInfo, [coder decodeObject]); 00333 ASSIGN(_subentities, [coder decodeObject]); 00334 _superentity = [coder decodeObject]; 00335 _model = [coder decodeObject]; 00336 [coder decodeValueOfObjCType: @encode(unsigned int) 00337 at: &_modelRefCount]; 00338 } 00339 00340 } 00341 return self; 00342 } 00343 00344 - (void) encodeWithCoder: (NSCoder *) coder 00345 { 00346 if ([coder allowsKeyedCoding]) 00347 { 00348 [coder encodeObject: _name forKey: @"Name"]; 00349 [coder encodeBool: _abstract forKey: @"Abstract"]; 00350 [coder encodeObject: _managedObjectClassName 00351 forKey: @"ManagedObjectClassName"]; 00352 [coder encodeObject: _properties forKey: @"Properties"]; 00353 [coder encodeObject: _userInfo forKey: @"UserInfo"]; 00354 [coder encodeObject: _subentities forKey: @"SubEntities"]; 00355 [coder encodeObject: _superentity forKey: @"SuperEntity"]; 00356 [coder encodeObject: _model forKey: @"ManagedObjectModel"]; 00357 [coder encodeInt: _modelRefCount forKey: @"ModelReferenceCount"]; 00358 } 00359 else 00360 { 00361 [coder encodeObject: _name]; 00362 [coder encodeValueOfObjCType: @encode(BOOL) at: &_abstract]; 00363 [coder encodeObject: _managedObjectClassName]; 00364 [coder encodeObject: _properties]; 00365 [coder encodeObject: _userInfo]; 00366 [coder encodeObject: _subentities]; 00367 [coder encodeObject: _superentity]; 00368 [coder encodeObject: _model]; 00369 [coder encodeValueOfObjCType: @encode(unsigned int) 00370 at: &_modelRefCount]; 00371 } 00372 } 00373 00389 - (void) _addReferenceToManagedObjectModel: (NSManagedObjectModel *) aModel 00390 { 00391 // don't allow re-setting the owner like this 00392 NSAssert(aModel != nil && (_model == nil || _model == aModel), 00393 _(@"Attempted to forcefully change the reference from an entity " 00394 @"to it's managed object model owner or ``nil'' model argument " 00395 @"passed.")); 00396 00397 _model = aModel; 00398 _modelRefCount++; 00399 } 00400 00401 - (void) _removeReferenceToManagedObjectModel: (NSManagedObjectModel *) aModel 00402 { 00403 NSAssert(_model == aModel, _(@"Attempted to forcefully remove the " 00404 @"reference from an entity to it's managed object model by some other, " 00405 @"unrelated model.")); 00406 NSAssert(_modelRefCount > 0, _(@"Attempted to underflow the " 00407 @"reference count from an entity to it's managed object model.")); 00408 00409 _modelRefCount--; 00410 if (_modelRefCount == 0) 00411 { 00412 _model = nil; 00413 } 00414 } 00415 00416 @end