/* 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 "SoClassRegistry.h" #include "SoObjCClass.h" #include "common.h" @implementation SoClassRegistry // TODO: register for bundle-did-load notification !! static SoClassRegistry *registry = nil; // THREAD + (id)sharedClassRegistry { if (registry == nil) registry = [[SoClassRegistry alloc] init]; return registry; } - (id)init { if ((self = [super init])) { self->objcToSoClass = [[NSMutableDictionary alloc] initWithCapacity:64]; self->extToSoClass = [[NSMutableDictionary alloc] initWithCapacity:32]; self->nameToSoClass = [[NSMutableDictionary alloc] initWithCapacity:32]; } return self; } - (void)dealloc { [self->extToSoClass release]; [self->nameToSoClass release]; [self->objcToSoClass release]; [super dealloc]; } /* name registry */ - (SoClass *)soClassWithName:(NSString *)_name { Class clazz; if ([_name length] == 0) return nil; if ((clazz = NSClassFromString(_name))) return [self soClassForClass:clazz]; return nil; } - (SoClass *)soClassForExtension:(NSString *)_ext { SoClass *soClass; if ((soClass = [self->extToSoClass objectForKey:_ext]) == nil) return nil; return soClass; } - (NSException *)registerSoClass:(SoClass *)_clazz forExtension:(NSString *)_e{ SoClass *soClass; NSAssert(_clazz, @"invalid class parameter !"); NSAssert(_e, @"invalid file extension parameter !"); if ((soClass = [self->extToSoClass objectForKey:_e])) { if (soClass == _clazz) /* already registered */ return nil; [self debugWithFormat: @"overriding existing registration for extension '%@': %@", _e, soClass]; } [self->extToSoClass setObject:_clazz forKey:_e]; return nil; } - (SoClass *)soClassForExactName:(NSString *)_name { SoClass *soClass; if ((soClass = [self->nameToSoClass objectForKey:_name]) == nil) return nil; return soClass; } - (NSException *)registerSoClass:(SoClass *)_clazz forExactName:(NSString *)_n{ SoClass *soClass; NSAssert(_clazz, @"invalid class parameter !"); NSAssert(_n, @"invalid file extension parameter !"); if ((soClass = [self->nameToSoClass objectForKey:_n])) { if (soClass == _clazz) /* already registered */ return nil; [self debugWithFormat: @"overriding existing registration for name '%@': %@", _n, soClass]; } [self->nameToSoClass setObject:_clazz forKey:_n]; return nil; } /* ObjC classes */ - (SoClass *)soClassForClass:(Class)_clazz { SoObjCClass *soClass; SoClass *soSuper; if (_clazz == Nil) return nil; if ((soClass = [self->objcToSoClass objectForKey:_clazz])) return soClass; soSuper = [self soClassForClass:[_clazz superclass]]; soClass = [[SoObjCClass alloc] initWithSoSuperClass:soSuper class:_clazz]; if (soClass == nil) { [self debugWithFormat:@"could not create SoClass for class %@ !", _clazz]; return nil; } [self->objcToSoClass setObject:soClass forKey:_clazz]; [soClass rescanClass]; [self debugWithFormat:@"mapped class %@ to SoClass %@", NSStringFromClass(_clazz), soClass]; return [soClass autorelease]; } @end /* SoClassRegistry */ @implementation SoClassRegistry(Logging) - (NSString *)loggingPrefix { return @"[so-class-registry]"; } - (BOOL)isDebuggingEnabled { static int debugOn = -1; if (debugOn == -1) { debugOn = [[NSUserDefaults standardUserDefaults] boolForKey:@"SoClassRegistryDebugEnabled"] ? 1 : 0; } return debugOn ? YES : NO; } @end /* SoClassRegistry(Logging) */