From: helge Date: Mon, 6 Sep 2004 14:48:24 +0000 (+0000) Subject: modification to resource lookup X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=471d48bb092b0c89b6c193c759287c0aa64d1687;p=sope modification to resource lookup git-svn-id: http://svn.opengroupware.org/SOPE/trunk@111 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-core/NGExtensions/ChangeLog b/sope-core/NGExtensions/ChangeLog index 50e287cb..da7dd14b 100644 --- a/sope-core/NGExtensions/ChangeLog +++ b/sope-core/NGExtensions/ChangeLog @@ -1,3 +1,10 @@ +2004-09-06 Helge Hess + + * 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 * v4.3.112 diff --git a/sope-core/NGExtensions/NGBundleManager.m b/sope-core/NGExtensions/NGBundleManager.m index cf04d950..c44a2d5f 100644 --- a/sope-core/NGExtensions/NGBundleManager.m +++ b/sope-core/NGExtensions/NGBundleManager.m @@ -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]; diff --git a/sope-core/NGExtensions/Version b/sope-core/NGExtensions/Version index 1ddcd53e..c2c9a8e5 100644 --- a/sope-core/NGExtensions/Version +++ b/sope-core/NGExtensions/Version @@ -1,5 +1,5 @@ # version -SUBMINOR_VERSION:=112 +SUBMINOR_VERSION:=113 # v4.2.72 requires libEOControl v4.2.39