bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC/PATCH] EOModel


From: David Ayers
Subject: [RFC/PATCH] EOModel
Date: Tue, 26 Nov 2002 23:59:46 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2a) Gecko/20020910

Hello Everyone,

Here's a patch to support more programatic model manipulation:

- corrected typo in method name -encodeTableOfContentsPropertyList:path:
- moved interface declaration of privat methods from header to source file
- initialize new model with current version
- removed commented duplicate code to _registerClassDescForClass: and _registerClass_descForEntityName:
- implemented description
- added private method _formatModelPath:checkFileSystem
- used new _formatModelPath:checkFileSystem method when loading and saving paths instead of findPathForModelNamed: - reimplemented initWithContentsOfFile: - unlike EOF, this method will automatically try to add the correct file extension - reimplemented initWithTableOfContentsPropertyList:path: - ditto - I'm not sure which version to default to if model doesn't contain version info. For now I've followed the orignal behavior which defaulted to 0. - corrected the plist format of the entity.plist files by removing the encapsulating array.
- corrected _setPath: to set the correct model name.
- changed _verifyBuiltEntityObject:named: to use the actual path of the model instead of findPathForModelNamed:
- removed some old commented code

Cheers,
Dave

PS: I orignially wanted to patch findPathForModelNamed: to use NSSearchPathForDirectoriesInDomains, but the current implemetation seems so unusual, that I would prefer to remove it. It seaches the main bundels resource directory for the model (which the global modal group would also); then it interprets the path as the location of a loadable bundle and if it is, searches its resource directory; then it searches for a loadable bundle named "Models" in ~/Library, /LocalLibrary and /NextLibrary, and if it finds it searches its resource directory. I think this method should be removed, but maybe someone can convince me otherwise.

PPS: Once these patches are through, I'll can submit my preliminary start of a Testing suite.

Index: dev-libs/gdl2/EOAccess/EOModel.h
===================================================================
RCS file: /cvsroot/gnustep/gnustep/dev-libs/gdl2/EOAccess/EOModel.h,v
retrieving revision 1.2
diff -u -r1.2 EOModel.h
--- dev-libs/gdl2/EOAccess/EOModel.h    25 Nov 2002 20:01:42 -0000      1.2
+++ dev-libs/gdl2/EOAccess/EOModel.h    26 Nov 2002 23:04:50 -0000
@@ -115,7 +115,7 @@
 
 - (id) initWithTableOfContentsPropertyList: (NSDictionary *)tableOfContents
                                       path: (NSString *)path;
-- (void)encodeTableOfContentsInfoPropertyList: (NSMutableDictionary 
*)propertyList;
+- (void)encodeTableOfContentsIntoPropertyList: (NSMutableDictionary 
*)propertyList;
 
 - (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList;
 - (void)awakeWithPropertyList: (NSDictionary *)propertyList;
@@ -176,14 +176,5 @@
 @end
 
 extern NSString *EOEntityLoadedNotification;
-
-@interface EOModel (EOModelPrivate)
-
-- (void)setCreateMutableObjects: (BOOL)flag;
-- (BOOL)createsMutableObjects;
-- (EOEntity *)_verifyBuiltEntityObject: (id)entity
-                                 named: (NSString *)name;
-
-@end /* EOModel (EOModelPrivate) */
 
 #endif /* __EOModel_h__ */
Index: dev-libs/gdl2/EOAccess/EOModel.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/dev-libs/gdl2/EOAccess/EOModel.m,v
retrieving revision 1.2
diff -u -r1.2 EOModel.m
--- dev-libs/gdl2/EOAccess/EOModel.m    25 Nov 2002 20:01:42 -0000      1.2
+++ dev-libs/gdl2/EOAccess/EOModel.m    26 Nov 2002 23:04:51 -0000
@@ -40,7 +40,6 @@
 #import <Foundation/NSValue.h>
 #import <Foundation/NSUtilities.h>
 #import <Foundation/NSObjCRuntime.h>
-
 #import <Foundation/NSException.h>
 
 #import <EOAccess/EOModel.h>
@@ -63,6 +62,17 @@
 
 NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
 
+@interface EOModel (EOModelPrivate)
+
++ (NSString *)_formatModelPath: (NSString *)path checkFileSystem: (BOOL)chkFS;
+
+- (void)setCreateMutableObjects: (BOOL)flag;
+- (BOOL)createsMutableObjects;
+- (EOEntity *)_verifyBuiltEntityObject: (id)entity
+                                 named: (NSString *)name;
+
+@end /* EOModel (EOModelPrivate) */
+
 
 @implementation EOModel
 
@@ -173,6 +183,7 @@
   if ((self = [super init]))
     {
       // Turbocat
+      _version = 2;
       _flags.createsMutableObjects = YES;
       
       _entitiesByName = [GCMutableDictionary new];
@@ -270,48 +281,6 @@
   return YES;
 }
 
-/*Mirko:
-- (void)_registerClassDescForClass:(NSNotification *)notification
-{
-  EOEntityClassDescription *classDesc = nil;
-  Class aClass = [notification object];
-  int i;
-
-  if (_entitiesByClass == NULL)
-    return;
-
-  for (i = 0; ((Class *)_entitiesByClass)[i]; i = i + 2)
-    {
-      if(aClass == ((Class *)_entitiesByClass)[i])
-       {
-          classDesc = [EOEntityClassDescription 
entityClassDescriptionWithEntity: ((EOEntity **)_entitiesByClass)[i+1]];
-
-         [EOClassDescription registerClassDescription:classDesc
-                             forClass:aClass];
-
-         return;
-       }
-    }
-}
-
-- (void)_registerClassDescForEntityName:(NSNotification *)notification
-{
-  EOEntityClassDescription *classDesc;
-  NSString *entityName = [notification object];
-  EOEntity *entity;
-
-  entity = [self entityNamed:entityName];
-
-  if (entity)
-    {
-      classDesc = [EOEntityClassDescription entityClassDescriptionWithEntity: 
entity];
-
-      [EOClassDescription registerClassDescription: classDesc
-                         forClass: NSClassFromString([entity className])];
-    }
-}
-*/
-
 - (NSString *)path
 {
   return _path;
@@ -461,6 +430,28 @@
   return _userInfo;
 }
 
+- (NSString *)description
+{
+  NSMutableDictionary *descdict;
+  id obj;
+
+  descdict = [NSMutableDictionary dictionaryWithCapacity: 6];
+  obj = [self name];
+  if (obj) [descdict setObject: obj forKey: @"name"];
+  obj = [self adaptorName];
+  if (obj) [descdict setObject: obj forKey: @"adaptorName"];
+  obj = [self connectionDictionary];
+  if (obj) [descdict setObject: obj forKey: @"connectionDictionary"];
+  obj = [self userInfo];
+  if (obj) [descdict setObject: obj forKey: @"userInfo"];
+  obj = [self entities];
+  if (obj) [descdict setObject: obj forKey: @"entities"];
+  obj = [self storedProcedures];
+  if (obj) [descdict setObject: obj forKey: @"storedProcedures"];
+
+  return [descdict description];
+}
+
 - (NSString *)docComment
 {
   return _docComment;
@@ -490,69 +481,44 @@
 {
   NS_DURING
     {
-      NSDictionary *propList = nil;
-      NSString *completePath = [[self class] findPathForModelNamed: path];
+      NSString *name = nil;
+      NSString *modelPath = nil;
       NSString *indexPath = nil;
+      NSString *fileContents = nil;
+      NSDictionary *propList = nil;
 
-      NSDebugMLLog(@"gsdb", @"path=%@", path);
-      NSDebugMLLog(@"gsdb", @"completePath=%@", completePath);
-
-      if ([[completePath pathExtension] isEqualToString: @"eomodeld"])
-        indexPath = [completePath stringByAppendingPathComponent:
-                                   @"index.eomodeld"];
-      else
-        indexPath = completePath;
-
-      NSDebugMLLog(@"gsdb", @"path=%@ completePath=%@ indexPath=%@",
-                  path, completePath, indexPath);
-
-      propList = [[NSString stringWithContentsOfFile: indexPath] propertyList];
-      NSDebugMLLog(@"gsdb", @"propList=%@", propList);
-
-      if (!propList)
-        {
-          NSLog(@"Loading model (path=%@ \n index path=%@) failed",
-                path,
-                indexPath);
-
-          //Try loading directly from path
-          if ([[path pathExtension] isEqualToString: @"eomodeld"])
-            indexPath = [path stringByAppendingPathComponent:
-                               @"index.eomodeld"];
-          else
-            indexPath = path;
-
-          NSDebugMLLog(@"gsdb", @"path=%@ completePath=%@ indexPath=%@",
-                      path, completePath, indexPath);
-
-          propList = [[NSString stringWithContentsOfFile: indexPath] 
propertyList];
-
-          NSDebugMLLog(@"gsdb", @"propList=%@", propList);
-        }
+      path = [path stringByStandardizingPath];
+      modelPath = [isa _formatModelPath: path checkFileSystem: YES];
+      NSAssert1(modelPath!=nil, @"Model does not exist at path %@",
+                path );
+      name = [[modelPath lastPathComponent] stringByDeletingPathExtension];
+      [self setName: name];
 
-      //TODO test it
-      NSAssert2(propList, @"Loading model (path=%@ \n index path=%@) failed",
-                path,
-                indexPath);
-
-      //what to do if it fail ?
-      if ((self = [self initWithTableOfContentsPropertyList: propList
-                       path: path]))
+      if ([[modelPath pathExtension] isEqualToString: @"eomodeld"])
         {
+          indexPath =
+              [modelPath stringByAppendingPathComponent: @"index.eomodeld"];
         }
       else
         {
-          NSEmitTODO();  
-          return [self notImplemented: _cmd]; //TODO
+          indexPath = modelPath;
         }
+
+      fileContents = [NSString stringWithContentsOfFile: indexPath];
+      propList = [fileContents propertyList];
+      NSDebugMLLog(@"gsdb", @"propList=%@", propList);
+      NSAssert1(propList!=nil, @"Model at path %@ is invalid", indexPath);
+
+      self = [self initWithTableOfContentsPropertyList: propList
+                   path: modelPath];
+      NSAssert2(self!=nil,@"Failed to initialize with path %@ and plist %@",
+                modelPath,
+                propList);
     }
   NS_HANDLER
     {
       NSLog(@"exception in EOModel initWithContentsOfFile:");
       NSLog(@"exception=%@", localException);
-/*      localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
-                                                              @"In EOModel 
initWithContentsOfFile:");*/
-      NSLog(@"exception=%@", localException);
       [localException raise];
     }
   NS_ENDHANDLER;
@@ -580,13 +546,11 @@
   while ((entityPList = [entityEnum nextObject]))
     {
       NSString *fileName;
-      NSArray *entityArray;
 
       fileName = [path stringByAppendingPathComponent:
                         [NSString stringWithFormat: @"%@.plist",
                                   [entityPList objectForKey: @"name"]]];
-      entityArray = [NSArray arrayWithObject: entityPList];
-      [entityArray writeToFile: fileName atomically: YES];
+      [entityPList writeToFile: fileName atomically: YES];
     }
 
   {
@@ -595,7 +559,7 @@
     fileName = [path stringByAppendingPathComponent: @"index.eomodeld"];
 
     [pList removeAllObjects];
-    [self encodeTableOfContentsInfoPropertyList: pList];
+    [self encodeTableOfContentsIntoPropertyList: pList];
     [pList writeToFile:fileName atomically: YES];
   }
 }
@@ -612,35 +576,36 @@
     {
       if ((self = [self init]))
         {
+          NSString *name;
           NSString *versionString = nil;
-          NSArray *entities = nil;
+          NSArray  *entities = nil;
           int i, count = 0;
 
-          [self _setPath: path];
-          _name = [[EOModel findPathForModelNamed: _path] retain];
-
           NSDebugMLLog(@"gsdb", @"tableOfContents=%@", tableOfContents);
-          NSAssert1(_name, @"No name for model (path=%@)", path);          
 
-          [self setName: _name];//??
-          versionString = [tableOfContents objectForKey: @"EOModelVersion"];
+         /* The call to _setPath: also sets the name implicitly. */
+          [self _setPath: [isa _formatModelPath: path checkFileSystem: YES]];
+          NSDebugMLLog(@"gsdb", @"name=%@ path=%@", _name, _path);
 
+          versionString = [tableOfContents objectForKey: @"EOModelVersion"];
           if (versionString)
             _version = [versionString floatValue];
+          else
+            _version = 0; // dayers: is this correct?
 
           ASSIGN(_connectionDictionary,
-                [tableOfContents objectForKey: @"connectionDictionary"]);
+                 [tableOfContents objectForKey: @"connectionDictionary"]);
           ASSIGN(_adaptorName, [tableOfContents objectForKey: @"adaptorName"]);
           ASSIGN(_userInfo, [tableOfContents objectForKey: @"userInfo"]);
 
           if (!_userInfo)
             {
               ASSIGN(_userInfo,
-                    [tableOfContents objectForKey:@"userDictionary"]);
+                     [tableOfContents objectForKey:@"userDictionary"]);
             }
 
           ASSIGN(_internalInfo,
-                [tableOfContents objectForKey: @"internalInfo"]);
+                 [tableOfContents objectForKey: @"internalInfo"]);
           ASSIGN(_docComment,[tableOfContents objectForKey:@"docComment"]);
 
           //VERIFY
@@ -648,7 +613,7 @@
             {
               NSMutableDictionary *markSP = [NSMutableDictionary dictionary];
               NSArray *storedProcedures = [tableOfContents
-                                           objectForKey: @"storedProcedures"];
+                                           objectForKey: @"storedProcedures"];
               EOStoredProcedure *sp = nil;
               NSEnumerator *enumerator = nil;
 
@@ -662,10 +627,10 @@
 
                   fileName = [NSString stringWithFormat: @"%@.storedProcedure",
                                        [[storedProcedures objectAtIndex: i]
-                                        objectForKey: @"name"]];         
+                                         objectForKey: @"name"]];        
                   plist = [[NSString stringWithContentsOfFile:
                                        [_name stringByAppendingPathComponent:
-                                               fileName]]
+                                                fileName]]
                             propertyList];       
 
                   [markSP setObject: plist
@@ -687,7 +652,7 @@
           for (i = 0; i < count; i++)
             {
               [self _addFakeEntityWithPropertyList:
-                     [entities objectAtIndex: i]];
+                      [entities objectAtIndex: i]];
             }
         }
     }
@@ -695,9 +660,6 @@
     {
       NSLog(@"exception in EOModel initWithTableOfContentsPropertyList:path:");
       NSLog(@"exception=%@", localException);
-/*      localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
-                                                              @"In EOModel 
initWithTableOfContentsPropertyList:path:");*/
-      NSLog(@"exception=%@", localException);
       [localException raise];
     }
   NS_ENDHANDLER;
@@ -705,7 +667,7 @@
   return self;
 }
 
-- (void)encodeTableOfContentsInfoPropertyList: (NSMutableDictionary 
*)propertyList
+- (void)encodeTableOfContentsIntoPropertyList: (NSMutableDictionary 
*)propertyList
 {
   int i, count;
   NSMutableArray *entitiesArray;
@@ -881,10 +843,6 @@
     {
       NSLog(@"exception in EOModel initWithPropertyList:owner:");
       NSLog(@"exception=%@", localException);
-/*      localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
-                                                              @"In EOModel 
initWithPropertyList:owner:");
-*/
-      NSLog(@"exception=%@", localException);
       [localException raise];
     }
   NS_ENDHANDLER;
@@ -1064,14 +1022,13 @@
   return nil;
 }
 
-
 - (void)_setPath: (NSString*)path
 {
   //OK
   [self loadAllModelObjects];
   [self willChange];
   ASSIGN(_path,path);
-  [self setName: [path stringByDeletingPathExtension]];//VERIFY
+  [self setName: [[path lastPathComponents] stringByDeletingPathExtension]];
 }
 
 - (EOEntity*)_entityForClass: (Class)aClass
@@ -1318,15 +1275,6 @@
       _entities = [_entities copy];
     }
 
-/*
-  count = [_entities count];
-
-  entitiesClass = calloc(count, sizeof(id));
-  memcpy(entitiesClass, _entitiesByClass, sizeof(Class)*(count-1));
-  ((Class *)entitiesClass)[count-1] = [entity class];
-  free(_entitiesByClass);
-  _entitiesByClass = entitiesClass;
-*/
   NSAssert(_entitiesByClass, @"No _entitiesByClass");
 
   className = [entity className];
@@ -1344,28 +1292,11 @@
 
 - (void)removeEntity: (EOEntity *)entity
 {
-//  unsigned int entityIndex = [_entities indexOfObject:entity];
   NSString *className = nil;
-//  void *entitiesClass=NULL;
-//  int count;
 
   [entity setModel: nil];
   [_entitiesByName removeObjectForKey: [entity name]];
 
-/*  count = [_entities count]-1;
-  if(count)
-    {
-      entitiesClass = calloc(count, sizeof(id));
-      if(entityIndex)
-       memcpy(entitiesClass, _entitiesByClass, sizeof(id)*entityIndex);
-      if(count > entityIndex)
-       memcpy(&((int *)entitiesClass)[entityIndex],
-              &((int *)_entitiesByClass)[entityIndex+1],
-              sizeof(id)*(count-entityIndex));
-    }
-  free(_entitiesByClass);
-  _entitiesByClass = entitiesClass;
-*/
   NSAssert(_entitiesByClass, @"No _entitiesByClass");
 
   className = [entity className];
@@ -1517,6 +1448,75 @@
 @end
 
 @implementation EOModel (EOModelPrivate)
+/**
+ * Returns a string that can be uses as a model path to load or save
+ * the model.  If chkFS is YES, then the path is searched.  If path
+ * does not include a path extension then first .eomodeld checked.  If that
+ * fails then .eomodel is searched.  Call this method to format the path
+ * provided before saving the model with chkFS NO.  Call this method to
+ * format the path provided before loading a model with chkFS YES.
+ */
++ (NSString *)_formatModelPath: (NSString *)path checkFileSystem: (BOOL)chkFS
+{
+  NSFileManager *fileManager;
+  NSString *lastPathComponent = nil;
+  NSString *pathExtension = nil;
+  NSString *searchPath = path;
+  NSString *returnPath = path;
+
+  lastPathComponent = [path lastPathComponent];
+  pathExtension = [lastPathComponent pathExtension];
+
+  if ([lastPathComponent isEqualToString: @"index.eomodeld"] == NO)
+    {
+      if ([pathExtension isEqualToString: @"eomodeld"] == NO)
+       {
+         searchPath =
+             [searchPath stringByAppendingPathExtension: @"eomodeld"];
+       }
+      searchPath =
+         [searchPath stringByAppendingPathComponent: @"index.eomodeld"];
+    }
+        
+  searchPath = [searchPath stringByStandardizingPath];
+
+  if (chkFS==YES)
+    {
+      fileManager = [NSFileManager defaultManager];
+
+      if ([fileManager fileExistsAtPath: searchPath] == YES)
+        {
+          returnPath = searchPath;
+       }
+      else
+        {
+         searchPath = path;
+          if ([pathExtension isEqualToString: @"eomodel"] == NO)
+           {
+             searchPath =
+                 [searchPath stringByAppendingPathComponent: @"eomodel"];
+           }
+         searchPath = [searchPath stringByStandardizingPath];
+         if ([fileManager fileExistsAtPath: searchPath] == YES)
+           {
+             returnPath = searchPath;
+           }
+       }
+      NSAssert1(returnPath!=nil,@"No valid Model found at path:%@", path);
+    }
+  else 
+    {
+      returnPath = searchPath;
+    }
+
+  lastPathComponent = [returnPath lastPathComponent];
+  if ([lastPathComponent isEqualToString: @"index.eomodeld"] == YES)
+    {
+      returnPath = [returnPath stringByDeletingLastPathComponent];
+    }
+
+  return returnPath;
+}
 
 - (void)setCreateMutableObjects: (BOOL)flag
 {
@@ -1539,7 +1539,7 @@
 - (EOEntity *)_verifyBuiltEntityObject: (id)entity
                                  named: (NSString*)name
 {
-  if (![entity isKindOfClass: [EOEntity class]])
+  if (![entity isKindOfClass: [EOEntity class]]))
     {
       [EOObserverCenter suppressObserverNotification];
 
@@ -1558,7 +1558,7 @@
           NSAssert1(name, @"No name for entity %@", entity);
           NSDebugMLLog(@"gsdb", @"[self path]=%@", [self path]);
 
-          basePath = [[self class] findPathForModelNamed: [self path]]; 
+          basePath = [self path]; 
           [[entity retain] autorelease]; //so it won't be lost in _removeEntity
 
           NSDebugMLLog(@"gsdb", @"basePath =%@", basePath);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]