From 7d195f29d181e224c2eb0808d95c351227f0df81 Mon Sep 17 00:00:00 2001 From: Nikita Zhuk Date: Sun, 5 Jun 2011 15:15:34 +0300 Subject: [PATCH 1/5] - Added a new option: --includeh FILE : Generates an aggregate header file which #imports all header files of "human-generated" source files, i.e. all those Entity.h files --- mogenerator.h | 1 + mogenerator.m | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mogenerator.h b/mogenerator.h index 97773f13..0cf4da60 100644 --- a/mogenerator.h +++ b/mogenerator.h @@ -46,6 +46,7 @@ NSManagedObjectModel *model; NSString *baseClass; NSString *includem; + NSString *includeh; NSString *templatePath; NSString *outputDir; NSString *machineDir; diff --git a/mogenerator.m b/mogenerator.m index 34722839..2dff83a8 100644 --- a/mogenerator.m +++ b/mogenerator.m @@ -330,6 +330,7 @@ - (void) application: (DDCliApplication *) app // For compatibility: {@"baseClass", 0, DDGetoptRequiredArgument}, {@"includem", 0, DDGetoptRequiredArgument}, + {@"includeh", 0, DDGetoptRequiredArgument}, {@"template-path", 0, DDGetoptRequiredArgument}, // For compatibility: {@"templatePath", 0, DDGetoptRequiredArgument}, @@ -353,7 +354,8 @@ - (void) printUsage; printf("\n" " -m, --model MODEL Path to model\n" " --base-class CLASS Custom base class\n" - " --includem FILE Generate aggregate include file\n" + " --includem FILE Generate aggregate include file for .m files for both human and machine generated source files\n" + " --includeh FILE Generate aggregate include file for .h files for human generated source files only\n" " --template-path PATH Path to templates (absolute or relative to model path)\n" " --template-group NAME Name of template group\n" " -O, --output-dir DIR Output directory\n" @@ -496,7 +498,10 @@ - (int) application: (DDCliApplication *) app gCustomBaseClass = [baseClass retain]; NSString * mfilePath = includem; + NSString * hfilePath = includeh; + NSMutableString * mfileContent = [NSMutableString stringWithString:@""]; + NSMutableString * hfileContent = [NSMutableString stringWithString:@""]; [self validateOutputPath:outputDir forType:@"Output"]; [self validateOutputPath:machineDir forType:@"Machine Output"]; @@ -657,6 +662,8 @@ - (int) application: (DDCliApplication *) app [mfileContent appendFormat:@"#import \"%@\"\n#import \"%@\"\n", [humanMFileName lastPathComponent], [machineMFileName lastPathComponent]]; + + [hfileContent appendFormat:@"#import \"%@\"\n", [humanHFileName lastPathComponent]]; } if (_listSourceFiles) { @@ -677,10 +684,20 @@ - (int) application: (DDCliApplication *) app [mfileContent writeToFile:mfilePath atomically:NO encoding:NSUTF8StringEncoding error:nil]; mfileGenerated = YES; } - + + bool hfileGenerated = NO; + if (hfilePath && ![hfileContent isEqualToString:@""]) { + [hfileContent writeToFile:hfilePath atomically:NO encoding:NSUTF8StringEncoding error:nil]; + hfileGenerated = YES; + } + if (!_listSourceFiles) { printf("%d machine files%s %d human files%s generated.\n", machineFilesGenerated, (mfileGenerated ? "," : " and"), humanFilesGenerated, (mfileGenerated ? " and one include.m file" : "")); + + if(hfileGenerated) { + printf("Aggregate header file was also generated to %s.\n", [hfilePath fileSystemRepresentation]); + } } return EXIT_SUCCESS; From e270cda6a8d5107abe947bcf2594fcac6c5150ed Mon Sep 17 00:00:00 2001 From: Nikita Zhuk Date: Sun, 5 Jun 2011 15:16:48 +0300 Subject: [PATCH 2/5] - Generate and use aggregate data model header file in PonsoTest project --- .../PonsoTest/PonsoTest.xcodeproj/project.pbxproj | 4 +++- .../PonsoTest/PonsoTest/PonsoTest-Prefix.pch | 1 + .../ponso/sample project/PonsoTest/PonsoTest/main.m | 7 +------ .../sample project/PonsoTest/Sources/DataModel/Model.h | 7 +++++++ .../PonsoTest/Sources/DataModel/ModelDepartmentAssistant.m | 2 -- .../PonsoTest/Sources/DataModel/ModelDepartmentEmployee.m | 2 -- .../PonsoTest/Sources/DataModel/ModelEmployee.m | 1 - ponso/generate.sh | 1 + 8 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/Model.h diff --git a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest.xcodeproj/project.pbxproj b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest.xcodeproj/project.pbxproj index 4e38107e..38c8a183 100644 --- a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest.xcodeproj/project.pbxproj +++ b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest.xcodeproj/project.pbxproj @@ -68,6 +68,7 @@ 4584D40E139A9D360035BCA5 /* ModelDepartmentEmployee.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ModelDepartmentEmployee.m; path = Sources/DataModel/ModelDepartmentEmployee.m; sourceTree = SOURCE_ROOT; }; 4584D40F139A9D360035BCA5 /* ModelEmployee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModelEmployee.h; path = Sources/DataModel/ModelEmployee.h; sourceTree = SOURCE_ROOT; }; 4584D410139A9D360035BCA5 /* ModelEmployee.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ModelEmployee.m; path = Sources/DataModel/ModelEmployee.m; sourceTree = SOURCE_ROOT; }; + 45F78872139BAA1900010BD3 /* Model.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Model.h; path = Sources/DataModel/Model.h; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -131,6 +132,7 @@ 457C26AF139A188D00BF00DD /* Data Model */ = { isa = PBXGroup; children = ( + 45F78872139BAA1900010BD3 /* Model.h */, 4584D3F9139A9D360035BCA5 /* _ModelAssistant.h */, 4584D3FA139A9D360035BCA5 /* _ModelAssistant.m */, 4584D3FB139A9D360035BCA5 /* _ModelCompany.h */, @@ -217,7 +219,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "### Settings\n\nDATA_MODEL_FILE=\"$PROJECT_DIR/MyModel.xcdatamodeld/MyModel.xcdatamodel\"\nDATA_MODEL_SOURCE_DIR=\"$PROJECT_DIR/Sources/DataModel\"\n\nBASE_CLASS=\"ModelObject\"\n\nMOGENERATOR_DIR=\"$PROJECT_DIR/../../../../../\"\nMOGENERATOR_BIN=\"$MOGENERATOR_DIR/mogenerator\" ## Adjust this so that it points to a compiled mogenerator binary.\nMOGENERATOR_TEMPLATES=\"$MOGENERATOR_DIR/contributed templates/Nikita Zhuk/ponso/templates\"\n\n### Logic\n\nsource \"$MOGENERATOR_DIR/ponso/generate.sh\"\n"; + shellScript = "### Settings\n\nDATA_MODEL_FILE=\"$PROJECT_DIR/MyModel.xcdatamodeld/MyModel.xcdatamodel\"\nDATA_MODEL_SOURCE_DIR=\"$PROJECT_DIR/Sources/DataModel\"\n\nBASE_CLASS=\"ModelObject\"\nAGGREGATE_HEADER=\"$DATA_MODEL_SOURCE_DIR/Model.h\"\n\nMOGENERATOR_DIR=\"$PROJECT_DIR/../../../../../\"\nMOGENERATOR_BIN=\"$MOGENERATOR_DIR/mogenerator\" ## Adjust this so that it points to a compiled mogenerator binary.\nMOGENERATOR_TEMPLATES=\"$MOGENERATOR_DIR/contributed templates/Nikita Zhuk/ponso/templates\"\n\n### Logic\n\nsource \"$MOGENERATOR_DIR/ponso/generate.sh\"\n"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/PonsoTest-Prefix.pch b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/PonsoTest-Prefix.pch index 0053d9e3..debd9cdf 100644 --- a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/PonsoTest-Prefix.pch +++ b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/PonsoTest-Prefix.pch @@ -4,4 +4,5 @@ #ifdef __OBJC__ #import + #import "Model.h" #endif diff --git a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/main.m b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/main.m index 11c48033..f463526e 100644 --- a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/main.m +++ b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/PonsoTest/main.m @@ -19,12 +19,7 @@ */ #import -#import "ModelCompany.h" -#import "ModelDepartment.h" -#import "ModelDepartmentAssistant.h" -#import "ModelDepartmentEmployee.h" -#import "ModelEmployee.h" -#import "ModelAssistant.h" +#import "Model.h" int main (int argc, const char * argv[]) { diff --git a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/Model.h b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/Model.h new file mode 100644 index 00000000..15503aae --- /dev/null +++ b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/Model.h @@ -0,0 +1,7 @@ +#import "ModelAssistant.h" +#import "ModelCompany.h" +#import "ModelDepartment.h" +#import "ModelDepartmentAssistant.h" +#import "ModelDepartmentEmployee.h" +#import "ModelEmployee.h" + diff --git a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentAssistant.m b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentAssistant.m index b15109ee..17f446c9 100644 --- a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentAssistant.m +++ b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentAssistant.m @@ -5,8 +5,6 @@ // #import "ModelDepartmentAssistant.h" -#import "ModelDepartment.h" -#import "ModelCompany.h" @implementation ModelDepartmentAssistant diff --git a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentEmployee.m b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentEmployee.m index 3bd85786..00f9207c 100644 --- a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentEmployee.m +++ b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelDepartmentEmployee.m @@ -5,8 +5,6 @@ // #import "ModelDepartmentEmployee.h" -#import "ModelDepartment.h" -#import "ModelCompany.h" @implementation ModelDepartmentEmployee diff --git a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelEmployee.m b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelEmployee.m index 29d0a48f..680e2457 100644 --- a/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelEmployee.m +++ b/contributed templates/Nikita Zhuk/ponso/sample project/PonsoTest/Sources/DataModel/ModelEmployee.m @@ -5,7 +5,6 @@ // #import "ModelEmployee.h" -#import "ModelCompany.h" @implementation ModelEmployee diff --git a/ponso/generate.sh b/ponso/generate.sh index dee37591..4f2fc2d9 100644 --- a/ponso/generate.sh +++ b/ponso/generate.sh @@ -18,6 +18,7 @@ MOMC_SUPPRESS_INVERSE_TRANSIENT_ERROR=YES \ "$MOGENERATOR_BIN" \ -m "$DATA_MODEL_FILE" \ --base-class "$BASE_CLASS" \ +--includeh "$AGGREGATE_HEADER" \ --template-path "$MOGENERATOR_TEMPLATES" \ -O "$DATA_MODEL_SOURCE_DIR" From d5c21ba75511f45f04907cc870fc4b9dd8692dc2 Mon Sep 17 00:00:00 2001 From: Nikita Zhuk Date: Sun, 5 Jun 2011 15:49:49 +0300 Subject: [PATCH 3/5] - Abort generate.sh script if mogenerator exits with a non-zero status --- ponso/generate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ponso/generate.sh b/ponso/generate.sh index 4f2fc2d9..57b9a6d6 100644 --- a/ponso/generate.sh +++ b/ponso/generate.sh @@ -20,6 +20,6 @@ MOMC_SUPPRESS_INVERSE_TRANSIENT_ERROR=YES \ --base-class "$BASE_CLASS" \ --includeh "$AGGREGATE_HEADER" \ --template-path "$MOGENERATOR_TEMPLATES" \ --O "$DATA_MODEL_SOURCE_DIR" +-O "$DATA_MODEL_SOURCE_DIR" || exit 1 echo "Generated Data Model Classes to $DATA_MODEL_SOURCE_DIR" From 4e9f4f5cd77a7da7176da1a5221d11a38618e3d6 Mon Sep 17 00:00:00 2001 From: Nikita Zhuk Date: Sun, 5 Jun 2011 15:51:11 +0300 Subject: [PATCH 4/5] - Added cycle detection support - To run a cycle detection on strong (non-transient) relationships, include the following tag into the template: <$checkNonTransientRelationshipCycles $> - This will cause mogenerator to exit with failure status if cycles are found. --- .../ponso/templates/machine.h.motemplate | 2 +- ponso/MKCNSEntityDescriptionAdditions.h | 4 +++ ponso/MKCNSEntityDescriptionAdditions.m | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/contributed templates/Nikita Zhuk/ponso/templates/machine.h.motemplate b/contributed templates/Nikita Zhuk/ponso/templates/machine.h.motemplate index 96c76c74..9733a04c 100755 --- a/contributed templates/Nikita Zhuk/ponso/templates/machine.h.motemplate +++ b/contributed templates/Nikita Zhuk/ponso/templates/machine.h.motemplate @@ -10,7 +10,7 @@ #import #import "ModelObject.h" - +<$checkNonTransientRelationshipCycles $> <$foreach Relationship noninheritedRelationships do$>@class <$Relationship.destinationEntity.managedObjectClassName$>; <$endforeach do$> diff --git a/ponso/MKCNSEntityDescriptionAdditions.h b/ponso/MKCNSEntityDescriptionAdditions.h index fd1b53d5..e4007744 100644 --- a/ponso/MKCNSEntityDescriptionAdditions.h +++ b/ponso/MKCNSEntityDescriptionAdditions.h @@ -25,4 +25,8 @@ /** @TypeInfo NSAttributeDescription */ @property(nonatomic, readonly) NSArray *noninheritedRelationshipsInIDKeyPathTopologicalOrder; +// Checks if the managed object model of the receiver contains cycles in non-transient relationships. +// If cycles are found, an exception is raised. +- (void)checkNonTransientRelationshipCycles; + @end diff --git a/ponso/MKCNSEntityDescriptionAdditions.m b/ponso/MKCNSEntityDescriptionAdditions.m index 03f001c4..24f51251 100644 --- a/ponso/MKCNSEntityDescriptionAdditions.m +++ b/ponso/MKCNSEntityDescriptionAdditions.m @@ -38,6 +38,22 @@ - (BOOL)includeRelationship:(NSRelationshipDescription *)relationship @end +@interface MKCNSRelationshipDescriptionNonTransientDependencyFilter : NSObject @end +@implementation MKCNSRelationshipDescriptionNonTransientDependencyFilter + +- (BOOL)includeRelationship:(NSRelationshipDescription *)relationship +{ + if([[relationship entity] isEqual:[relationship destinationEntity]]) + return NO; + + if([relationship isTransient]) + return NO; + + return YES; +} + +@end + @implementation NSEntityDescription(MKCNSEntityDescriptionAdditions) /** @TypeInfo NSAttributeDescription */ @@ -80,4 +96,17 @@ - (NSArray*)noninheritedRelationshipsInIDKeyPathTopologicalOrder return sortedRelationships; } +- (void)checkNonTransientRelationshipCycles +{ + id dependencyFilter = [[[MKCNSRelationshipDescriptionNonTransientDependencyFilter alloc] init] autorelease]; + NSArray *entities = [[self managedObjectModel] entitiesInTopologicalOrderUsingDependencyFilter:dependencyFilter]; + + if(entities == nil) + { + NSString *desc = @"Cycles were found in non-transient relationships."; + + [[NSException exceptionWithName:@"StrongRelationshipCyclesFoundException" reason:desc userInfo:nil] raise]; + } +} + @end From 7fa143d1bab756ab9316370d229ab4b5044076b4 Mon Sep 17 00:00:00 2001 From: Nikita Zhuk Date: Sun, 5 Jun 2011 15:51:54 +0300 Subject: [PATCH 5/5] - Updated PONSO README --- contributed templates/Nikita Zhuk/ponso/README.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/contributed templates/Nikita Zhuk/ponso/README.txt b/contributed templates/Nikita Zhuk/ponso/README.txt index 54fb8a71..730ffa03 100644 --- a/contributed templates/Nikita Zhuk/ponso/README.txt +++ b/contributed templates/Nikita Zhuk/ponso/README.txt @@ -33,7 +33,6 @@ Some missing features include: - Automatic setting of inverse one-to-one relationships in setters - Support for many-to-many relationships - Implementations of to-many relationships as ordered sets instead of arrays -- Cycle detection of strong relationships - Detection of retain cycles caused by both relationship directions being non-transient Feel free to fork & contribute.