]> err.no Git - sope/commitdiff
modification to resource lookup
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Mon, 6 Sep 2004 14:48:24 +0000 (14:48 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Mon, 6 Sep 2004 14:48:24 +0000 (14:48 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@111 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-core/NGExtensions/ChangeLog
sope-core/NGExtensions/NGBundleManager.m
sope-core/NGExtensions/Version

index 50e287cba7fbb1e45ab2c7d43dde9d1ea9220811..da7dd14bf676e475d3f612cc11dcd739497a64ab 100644 (file)
@@ -1,3 +1,10 @@
+2004-09-06  Helge Hess  <helge.hess@skyrix.com>
+
+       * NGBundleManager.m: changed bundle resource lookup to check loaded
+         bundles before scanning the NGBundlePath resources (is faster and
+         fixes an issue with a bundle loaded but not in the search path)
+         (v4.3.113)
+
 2004-09-05  Helge Hess  <helge.hess@opengroupware.org>
 
        * v4.3.112
index cf04d95004219432b27da47bc3282ad6b667e6e5..c44a2d5f8fe29813f662506fd6e21453c508d57b 100644 (file)
@@ -1229,104 +1229,160 @@ static BOOL _doesInfoMatch(NSArray *keys, NSDictionary *dict, NSDictionary *info
   return [[result copy] autorelease];
 }
 
+- (BOOL)_doesBundleInfo:(NSDictionary *)_bundleInfo path:(NSString *)_path
+  provideResource:(id)_resourceName ofType:(NSString *)_type
+  rnKeys:(NSArray *)_rnKeys
+  resourceSelector:(NGBundleResourceSelector)_selector context:(void *)_context
+{
+  NSEnumerator *providedResources;
+  NSDictionary *info;
+  
+  providedResources = 
+    [[(NSDictionary *)[_bundleInfo objectForKey:@"provides"] 
+                      objectForKey:_type] objectEnumerator];
+  if (providedResources == nil) return NO;
+  
+  /* scan provide array */
+  while ((info = [providedResources nextObject])) {
+    if (_rnKeys != nil) {
+      if (!_doesInfoMatch(_rnKeys, _resourceName, info))
+        continue;
+    }
+    else {
+      NSString *name;
+
+      name = [[(NSDictionary *)info objectForKey:@"name"] stringValue];
+      if (name == nil) continue;
+      if (![name isEqualToString:_resourceName]) continue;
+    }
+    
+    if (_selector != NULL) {
+      if (!_selector(_resourceName, _type, _path, info, self, _context))
+        continue;
+    }
+    
+    /* all conditions applied (found) */
+    return YES;
+  }
+  return NO;
+}
+
+- (NSString *)pathOfLoadedBundleProvidingResource:(id)_resourceName
+  ofType:(NSString *)_type
+  resourceSelector:(NGBundleResourceSelector)_selector context:(void *)_context
+{
+  NSMapEnumerator menum;
+  NSString     *path;
+  NSDictionary *bundleInfo;
+  NSArray      *rnKeys;
+  
+  rnKeys = ([_resourceName respondsToSelector:@selector(objectForKey:)])
+    ? [_resourceName allKeys]
+    : nil;
+  
+  menum = NSEnumerateMapTable(self->pathToBundleInfo);
+  while (NSNextMapEnumeratorPair(&menum, (void *)&path, (void *)&bundleInfo)) {
+    if (debugOn) {
+      NSLog(@"check loaded bundle for resource %@: %@", _resourceName,
+            path);
+    }
+    
+    if ([self _doesBundleInfo:bundleInfo path:path
+              provideResource:_resourceName ofType:_type rnKeys:rnKeys
+              resourceSelector:_selector context:_context])
+      /* strip bundle-info.plist name */
+      return [path stringByDeletingLastPathComponent];
+  }
+  
+  return nil;
+}
+
 - (NSString *)pathForBundleProvidingResource:(id)_resourceName
   ofType:(NSString *)_type
   resourceSelector:(NGBundleResourceSelector)_selector
   context:(void *)_context
 {
-  NSFileManager *fm = [NSFileManager defaultManager];
+  /* main path lookup method */
+  // TODO: this method seriously needs some refactoring
+  NSFileManager *fm;
   NSEnumerator  *e;
   NSString      *path;
   NSArray       *rnKeys = nil;
   int           rnKeyCount = 0;
-
+  
+  if (debugOn) {
+    NSLog(@"BM LOOKUP path (%d bundles loaded): %@ / %@", 
+          NSCountMapTable(self->loadedBundles), _resourceName, _type);
+  }
+  
+  /* look in loaded bundles */
+  
+  path = [self pathOfLoadedBundleProvidingResource:_resourceName ofType:_type
+               resourceSelector:_selector context:_context];
+  if (path != nil) return path;
+  
+  /* look in filesystem */
+  
   if ([_resourceName respondsToSelector:@selector(objectForKey:)]) {
     rnKeys     = [_resourceName allKeys];
     rnKeyCount = [rnKeys count];
   }
   
+  fm = [NSFileManager defaultManager];
   e = [self->bundleSearchPaths objectEnumerator];
-  while ((path = [e nextObject])) {
-    BOOL isDir = NO;
+  while ((path = [e nextObject]) != nil) {
+    NSEnumerator *dir;
+    BOOL     isDir = NO;
+    NSString *tmp;
+    id       info = nil;
     
-    if ([fm fileExistsAtPath:path isDirectory:&isDir]) {
-      NSString *tmp;
-      id info = nil;
+    if (![fm fileExistsAtPath:path isDirectory:&isDir])
+      continue;
+    
+    if (!isDir) continue;
+    
+    /* check whether an appropriate bundle is contained in 'path' */
+       
+    dir = [[fm directoryContentsAtPath:path] objectEnumerator];
+    while ((tmp = [dir nextObject])) {
+      NSDictionary *bundleInfo      = nil;
+      NSString     *infoPath;
       
-      if (!isDir) continue;
+      tmp      = [path stringByAppendingPathComponent:tmp];
+      infoPath = [self makeBundleInfoPath:tmp];
       
-      /* check whether an appropriate bundle is contained in 'path' */
-      {
-        NSEnumerator *dir;
-       
-        dir = [[fm directoryContentsAtPath:path] objectEnumerator];
-        while ((tmp = [dir nextObject])) {
-          NSDictionary *bundleInfo      = nil;
-          NSEnumerator *providedResources = nil;
-          NSString *infoPath;
-          id info;
-          
-          tmp = [path stringByAppendingPathComponent:tmp];
-          infoPath = [self makeBundleInfoPath:tmp];
-
-         if (debugOn)
-           NSLog(@"check path path=%@ info=%@", tmp, infoPath);
-         
-          if ((bundleInfo=NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
-            if (![fm fileExistsAtPath:infoPath])
-              continue;
-
-            bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
-          }
-         if (debugOn) {
-           NSLog(@"found info for path=%@ info=%@: %@", 
-                 tmp, infoPath, bundleInfo);
-         }
+      if (debugOn)
+        NSLog(@"check path path=%@ info=%@", tmp, infoPath);
          
-          providedResources = 
-            [[(NSDictionary *)[bundleInfo objectForKey:@"provides"]
-                                          objectForKey:_type]
-                                          objectEnumerator];
-          if (providedResources == nil) continue;
-
-          // scan provide array
-          while ((info = [providedResources nextObject])) {
-            if (rnKeys) {
-              if (!_doesInfoMatch(rnKeys, _resourceName, info))
-                continue;
-            }
-            else {
-              NSString *name;
+      if ((bundleInfo = NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
+        if (![fm fileExistsAtPath:infoPath])
+          continue;
 
-              name = [[(NSDictionary *)info objectForKey:@"name"] stringValue];
-              if (name == nil) continue;
-              if (![name isEqualToString:_resourceName]) continue;
-            }
-
-            if (_selector) {
-              if (!_selector(_resourceName, _type, tmp, info, self, _context))
-                continue;
-            }
-            /* all conditions applied */
-            return tmp;
-          }
-        }
+        bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
       }
-
-      /* check for direct match */
+      if (debugOn)
+        NSLog(@"found info for path=%@ info=%@: %@", tmp,infoPath,bundleInfo);
       
-      tmp = [self makeBundleInfoPath:path];
+      if ([self _doesBundleInfo:bundleInfo path:tmp
+                provideResource:_resourceName ofType:_type rnKeys:rnKeys
+                resourceSelector:_selector context:_context])
+        return tmp;
+    }
+    
+    /* check for direct match */
+      
+    tmp = [self makeBundleInfoPath:path];
 
-      if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
+    if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
         if ([fm fileExistsAtPath:tmp])
           info = [self _loadBundleInfoAtExistingPath:tmp];
         else if (debugOn) {
           NSLog(@"WARNING(%s): did not find direct path '%@'",
                 __PRETTY_FUNCTION__, tmp);
         }
-      }
+    }
       
-      if (info) {
+    if (info != nil) {
         // direct match (a bundle was specified in the path)
         NSEnumerator *providedResources;
         NSDictionary *provides;
@@ -1357,28 +1413,29 @@ static BOOL _doesInfoMatch(NSArray *keys, NSDictionary *dict, NSDictionary *info
           /* all conditions applied */
           return tmp;
         }
-      }
     }
   }
   return nil;
 }
 
-- (NSBundle *)bundleProvidingResource:(id)_resourceName
-  ofType:(NSString *)_resourceType
-{
+- (NSBundle *)bundleProvidingResource:(id)_name ofType:(NSString *)_type {
   NSString *bp;
   
-  bp = [self pathForBundleProvidingResource:_resourceName
-             ofType:_resourceType
+  if (debugOn) NSLog(@"BM LOOKUP: %@ / %@", _name, _type);
+  
+  bp = [self pathForBundleProvidingResource:_name
+             ofType:_type
              resourceSelector:NULL context:nil];
   if ([bp length] == 0) {
 #if (NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY) && HEAVY_DEBUG
     NSLog(@"%s: found no resource '%@' of type '%@' ...",
           __PRETTY_FUNCTION__, _resourceName, _resourceType);
 #endif
+    if (debugOn) NSLog(@"  did not find: %@ / %@", _name, _type);
     return nil;
   }
   
+  if (debugOn) NSLog(@"  FOUND: %@", bp);
   return [self bundleWithPath:bp];
 }
 
@@ -1424,6 +1481,29 @@ static BOOL _doesInfoMatch(NSArray *keys, NSDictionary *dict, NSDictionary *info
                                       objectForKey:_resourceType];
 }
 
+- (void)_addRegisteredProvidedResourcesOfType:(NSString *)_type
+  toSet:(NSMutableSet *)_result
+{
+  NSMapEnumerator menum;
+  NSString     *path;
+  NSDictionary *bundleInfo;
+  
+  menum = NSEnumerateMapTable(self->pathToBundleInfo);
+  while (NSNextMapEnumeratorPair(&menum, (void *)&path, (void *)&bundleInfo)) {
+    NSArray *providedResources;
+    
+    if (debugOn)
+      NSLog(@"check loaded bundle for resource types %@: %@", _type, path);
+    
+    providedResources = 
+      [(NSDictionary *)[bundleInfo objectForKey:@"provides"]
+                       objectForKey:_type];
+    if (providedResources == nil) continue;
+
+    [_result addObjectsFromArray:providedResources];
+  }
+}
+
 - (NSArray *)providedResourcesOfType:(NSString *)_resourceType {
   NSMutableSet  *result = nil;
   NSFileManager *fm = [NSFileManager defaultManager];
@@ -1432,67 +1512,73 @@ static BOOL _doesInfoMatch(NSArray *keys, NSDictionary *dict, NSDictionary *info
   
   result = [NSMutableSet setWithCapacity:128];
   
+  /* scan loaded bundles */
+  
+  [self _addRegisteredProvidedResourcesOfType:_resourceType toSet:result];
+  
+  /* scan all bundle search paths */
+  
   e = [self->bundleSearchPaths objectEnumerator];
   while ((path = [e nextObject])) {
-    BOOL isDir = NO;
+    NSEnumerator *dir;
+    BOOL     isDir = NO;
+    NSString *tmp;
+    id       info = nil;
 
-    if ([fm fileExistsAtPath:path isDirectory:&isDir]) {
-      NSString *tmp;
-      id info = nil;
-      if (!isDir) continue;
+    if (![fm fileExistsAtPath:path isDirectory:&isDir])
+      continue;
+    if (!isDir) continue;
 
-      /* check whether an appropriate bundle is contained in 'path' */
-      {
-        NSEnumerator *dir;
+    /* check whether an appropriate bundle is contained in 'path' */
 
-        dir = [[fm directoryContentsAtPath:path] objectEnumerator];
-        while ((tmp = [dir nextObject])) {
-          NSDictionary *bundleInfo      = nil;
-          NSArray      *providedResources = nil;
-          NSString     *infoPath;
+    dir = [[fm directoryContentsAtPath:path] objectEnumerator];
+    while ((tmp = [dir nextObject])) {
+      NSDictionary *bundleInfo      = nil;
+      NSArray      *providedResources = nil;
+      NSString     *infoPath;
           
-          tmp = [path stringByAppendingPathComponent:tmp];
-          infoPath = [self makeBundleInfoPath:tmp];
-
-         //NSLog(@"  info path: %@", tmp);
-
-          if ((bundleInfo = NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
-            if (![fm fileExistsAtPath:infoPath])
-              continue;
-
-            bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
-          }
+      tmp = [path stringByAppendingPathComponent:tmp];
+      infoPath = [self makeBundleInfoPath:tmp];
+      
+#if 0
+      NSLog(@"  info path: %@", tmp);
+#endif
 
-          providedResources = 
-            [(NSDictionary *)[bundleInfo objectForKey:@"provides"]
-                                         objectForKey:_resourceType];
-          if (providedResources == nil) continue;
+      if ((bundleInfo = NSMapGet(self->pathToBundleInfo, infoPath)) == nil) {
+        if (![fm fileExistsAtPath:infoPath])
+          continue;
 
-          [result addObjectsFromArray:providedResources];
-        }
+        bundleInfo = [self _loadBundleInfoAtExistingPath:infoPath];
       }
 
-      /* check for direct match */
+      providedResources = 
+        [(NSDictionary *)[bundleInfo objectForKey:@"provides"]
+                         objectForKey:_resourceType];
+      if (providedResources == nil) continue;
+
+      [result addObjectsFromArray:providedResources];
+    }
+    
+    /* check for direct match */
       
-      tmp = [self makeBundleInfoPath:path];
+    tmp = [self makeBundleInfoPath:path];
 
-      if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
-        if ([fm fileExistsAtPath:tmp])
-          info = [self _loadBundleInfoAtExistingPath:tmp];
-      }
+    if ((info = NSMapGet(self->pathToBundleInfo, tmp)) == nil) {
+      if ([fm fileExistsAtPath:tmp])
+        info = [self _loadBundleInfoAtExistingPath:tmp];
+    }
       
-      if (info) {
-        // direct match (a bundle was specified in the path)
-        NSArray      *providedResources;
-        NSDictionary *provides;
+    if (info != nil) {
+      // direct match (a bundle was specified in the path)
+      NSArray      *providedResources;
+      NSDictionary *provides;
 
-        provides          = [(NSDictionary *)info objectForKey:@"provides"];
-        providedResources = [provides objectForKey:_resourceType];
-        info = nil;
-        if (providedResources == nil) continue;
+      provides          = [(NSDictionary *)info objectForKey:@"provides"];
+      providedResources = [provides objectForKey:_resourceType];
+      info = nil;
+      if (providedResources == nil) continue;
 
-        [result addObjectsFromArray:providedResources];
-      }
+      [result addObjectsFromArray:providedResources];
     }
   }
   return [result allObjects];
index 1ddcd53ed4b387c67480535a7c8b5b0d93dc3fd0..c2c9a8e5543a7af32132870641769fefbe2daf16 100644 (file)
@@ -1,5 +1,5 @@
 # version
 
-SUBMINOR_VERSION:=112
+SUBMINOR_VERSION:=113
 
 # v4.2.72 requires libEOControl v4.2.39