/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. ****************************************************************/ #import "CAYDataMapIO.h" #import "CAYObjEntity.h" #import "CAYObjAttribute.h" #import "CAYObjRelationship.h" @implementation CAYDataMapIO +(NSManagedObjectModel *)dataMapAsManagedObjectModel:(CAYDataMap *)dataMap entityResolver:(CAYEntityResolver *)resolver { NSManagedObjectModel *cdModel = [[NSManagedObjectModel alloc] init]; // collect all properties (attributes, relationships) and set them after creating // all entities NSMutableDictionary *cdPropertiesByEntityName = [NSMutableDictionary dictionary]; // entities NSMutableDictionary *cdEntityByEntityName = [NSMutableDictionary dictionary]; NSMutableArray *cdEntities = [NSMutableArray array]; NSEnumerator *entityEnumerator = [[dataMap objEntityMap] keyEnumerator]; NSString *entityName = nil; while(entityName = [entityEnumerator nextObject]) { CAYObjEntity *cayEntity = [[dataMap objEntityMap] valueForKey:entityName]; NSEntityDescription *cdEntity = [[NSEntityDescription alloc] init]; [cdEntity setName:[cayEntity name]]; [cdEntity setManagedObjectClassName:[dataMap classNameForObjEntity:cayEntity]]; [cdEntityByEntityName setObject:cdEntity forKey:entityName]; // attributes NSMutableArray *cdAttributes = [NSMutableArray array]; NSEnumerator *cayAttributeEnumerator = [[cayEntity attributes] keyEnumerator]; NSString *attributeName = nil; while(attributeName = [cayAttributeEnumerator nextObject]) { CAYObjAttribute *cayAttribute = [[cayEntity attributes] valueForKey:attributeName]; NSAttributeDescription *cdAttribute = [[NSAttributeDescription alloc] init]; [cdAttribute setName:[cayAttribute name]]; [cdAttributes addObject:cdAttribute]; [cdAttribute release]; } [cdPropertiesByEntityName setObject:cdAttributes forKey:entityName]; [cdEntities addObject:cdEntity]; [cdEntity release]; } [cdModel setEntities:cdEntities]; // relationships. must be done after all entities are handled NSMutableDictionary *relationshipsByEntityName = [NSMutableDictionary dictionary]; entityEnumerator = [[dataMap objEntityMap] keyEnumerator]; while(entityName = [entityEnumerator nextObject]) { CAYObjEntity *cayEntity = [[dataMap objEntityMap] valueForKey:entityName]; NSMutableDictionary *relationshipsByRelationName = [NSMutableDictionary dictionary]; NSEnumerator *relEnumerator = [[cayEntity relationships] keyEnumerator]; NSMutableArray *properties = [cdPropertiesByEntityName valueForKey:entityName]; NSString *relName = nil; while(relName = [relEnumerator nextObject]) { CAYObjRelationship *cayRelationship = [[cayEntity relationships] valueForKey:relName]; NSRelationshipDescription *cdRelationship = [[NSRelationshipDescription alloc] init]; [cdRelationship setName:relName]; NSEntityDescription *destEntity = [cdEntityByEntityName valueForKey:[cayRelationship targetEntityName]]; [cdRelationship setDestinationEntity:destEntity]; // set min/max count based on toMany [cdRelationship setMinCount:0]; if([cayRelationship isToMany]) { // TODO: documentation says -1 for toMany, but ctrl-esc says unsigned int.. [cdRelationship setMaxCount:-1]; } else { [cdRelationship setMaxCount:1]; } [relationshipsByRelationName setObject:cdRelationship forKey:relName]; [properties addObject:cdRelationship]; [cdRelationship release]; } [relationshipsByEntityName setObject:relationshipsByRelationName forKey:entityName]; } // reverse relationships.. must be done after all relationships are created entityEnumerator = [[dataMap objEntityMap] keyEnumerator]; while(entityName = [entityEnumerator nextObject]) { CAYObjEntity *cayEntity = [[dataMap objEntityMap] valueForKey:entityName]; NSDictionary *cdRelationshipsByRelationName = [relationshipsByEntityName valueForKey:entityName]; NSEnumerator *relEnumerator = [[cayEntity relationships] keyEnumerator]; NSString *relName = nil; while(relName = [relEnumerator nextObject]) { CAYObjRelationship *cayRelationship = [[cayEntity relationships] valueForKey:relName]; NSRelationshipDescription *cdRelationship = [cdRelationshipsByRelationName objectForKey:[cayRelationship name]]; if(!cdRelationship) { NSLog(@"ERROR: did not find core data relationship. base: %@.%@", entityName, [cayRelationship name]); } NSMutableDictionary *cdInverseRelationshipsByRelationName = [relationshipsByEntityName valueForKey:[cayRelationship targetEntityName]]; NSRelationshipDescription *cdInverseRelationship = [cdInverseRelationshipsByRelationName valueForKey:[cayRelationship reverseRelationshipName]]; if(!cdInverseRelationship) { NSLog(@"ERROR: did not find core data relationship. base: %@.%@, inverse: %@.%@", entityName, [cayRelationship name], [cayRelationship targetEntityName], [cayRelationship reverseRelationshipName]); } [cdRelationship setInverseRelationship:cdInverseRelationship]; } } // set all properties NSEnumerator *propertiesEnumerator = [cdPropertiesByEntityName keyEnumerator]; while(entityName = [propertiesEnumerator nextObject]) { NSEntityDescription *cdEntity = [cdEntityByEntityName valueForKey:entityName]; NSArray *properties = [cdPropertiesByEntityName valueForKey:entityName]; [cdEntity setProperties:properties]; } return [cdModel autorelease]; } @end