/* Copyright (C) 2000-2005 SKYRIX Software AG This file is part of SOPE. SOPE is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. SOPE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with SOPE; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "NGResourceLocator.h" #include "NSNull+misc.h" #include "common.h" @implementation NGResourceLocator + (id)resourceLocatorForGNUstepPath:(NSString *)_path fhsPath:(NSString *)_fhs{ return [[[self alloc] initWithGNUstepPath:_path fhsPath:_fhs] autorelease]; } - (id)initWithGNUstepPath:(NSString *)_path fhsPath:(NSString *)_fhs { if ((self = [super init])) { self->gsSubPath = [_path copy]; self->fhsSubPath = [_fhs copy]; self->fileManager = [[NSFileManager defaultManager] retain]; self->flags.cacheSearchPathes = 1; self->flags.cachePathMisses = 1; self->flags.cachePathHits = 1; } return self; } - (id)init { return [self initWithGNUstepPath:@"Library/Resources" fhsPath:@"share"]; } - (void)dealloc { [self->nameToPathCache release]; [self->searchPathes release]; [self->fhsSubPath release]; [self->gsSubPath release]; [self->fileManager release]; [super dealloc]; } /* search pathes */ - (NSArray *)gsRootPathes { static NSArray *pathes = nil; NSDictionary *env; NSString *apath; if (pathes != nil) return [pathes isNotNull] ? pathes : nil; env = [[NSProcessInfo processInfo] environment]; if ((apath = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil) apath = [env objectForKey:@"GNUSTEP_PATHLIST"]; if (![apath isNotNull]) return nil; pathes = [[apath componentsSeparatedByString:@":"] copy]; return pathes; } - (NSArray *)fhsRootPathes { // TODO: we probably want to make this configurable?! At least with an envvar static NSArray *pathes = nil; if (pathes == nil) pathes = [[NSArray alloc] initWithObjects:@"/usr/local/", @"/usr/", nil]; return pathes; } - (NSArray *)collectSearchPathes { NSMutableArray *ma; NSEnumerator *e; NSString *p; ma = [NSMutableArray arrayWithCapacity:6]; e = ([self->gsSubPath length] > 0) ? [[self gsRootPathes] objectEnumerator] : nil; while ((p = [e nextObject])) { p = [p stringByAppendingPathComponent:self->gsSubPath]; if ([ma containsObject:p]) continue; if (![self->fileManager fileExistsAtPath:p]) continue; [ma addObject:p]; } e = ([self->fhsSubPath length] > 0) ? [[self fhsRootPathes] objectEnumerator] : nil; while ((p = [e nextObject])) { p = [p stringByAppendingPathComponent:self->fhsSubPath]; if ([ma containsObject:p]) continue; if (![self->fileManager fileExistsAtPath:p]) continue; [ma addObject:p]; } return ma; } - (NSArray *)searchPathes { NSArray *a; if (self->searchPathes != nil) return self->searchPathes; a = [self collectSearchPathes]; if (self->flags.cacheSearchPathes) { ASSIGNCOPY(self->searchPathes, a); return self->searchPathes; /* return copy */ } return a; } /* cache */ - (void)cachePath:(NSString *)_path forName:(NSString *)_name { if (self->nameToPathCache == nil) self->nameToPathCache = [[NSMutableDictionary alloc] initWithCapacity:64]; [self->nameToPathCache setObject:_path?_path:(id)[NSNull null] forKey:_name]; } /* operation */ - (NSString *)lookupFileWithName:(NSString *)_name { NSEnumerator *e; NSString *p; if (![_name isNotNull] || [_name length] == 0) return nil; if ((p = [self->nameToPathCache objectForKey:_name])) return [p isNotNull] ? p : nil; e = [[self searchPathes] objectEnumerator]; while ((p = [e nextObject])) { p = [p stringByAppendingPathComponent:_name]; if (![self->fileManager fileExistsAtPath:p]) continue; [self cachePath:p forName:_name]; return p; } if (self->flags.cachePathMisses) [self cachePath:nil forName:_name]; return nil; } - (NSString *)lookupFileWithName:(NSString *)_name extension:(NSString *)_ext { if ([_ext isNotNull] && [_ext length] > 0) _name = [_name stringByAppendingPathExtension:_ext]; return [self lookupFileWithName:_name]; } @end /* NGResourceLocator */