2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "OFSFactoryRegistry.h"
24 #include "OFSFolder.h"
26 #include "OFSFactoryContext.h"
27 #include "SoClassRegistry.h"
28 #include "SoObjCClass.h"
31 @interface SoClass(Factory)
32 - (id)ofsObjectFactory;
35 @implementation OFSFactoryRegistry
37 static int factoryDebugOn = 0;
38 static int factoryRegDebugOn = 0;
40 + (id)sharedFactoryRegistry {
42 if (reg == nil) reg = [[OFSFactoryRegistry alloc] init];
47 if ((self = [super init])) {
48 self->classToFileFactory =
49 [[NSMutableDictionary alloc] initWithCapacity:32];
50 self->extToFileFactory =
51 [[NSMutableDictionary alloc] initWithCapacity:64];
52 self->nameToFileFactory =
53 [[NSMutableDictionary alloc] initWithCapacity:64];
55 self->defaultFolderFactory = [OFSFolder class];
56 self->defaultFileFactory = [OFSFile class];
61 [self->defaultFileFactory release];
62 [self->defaultFolderFactory release];
63 [self->classToFileFactory release];
64 [self->extToFileFactory release];
65 [self->nameToFileFactory release];
71 - (id)factoryForChildKey:(NSString *)_key
72 ofFolder:(OFSFolder *)_folder
73 fileType:(NSString *)_ftype
74 mimeType:(NSString *)_mimeType
76 SoClassRegistry *classRegistry;
82 isDir = [_ftype isEqualToString:NSFileTypeDirectory] ? YES : NO;
85 [self debugWithFormat:@"lookup factory for key %@ type=%@ mime=%@",
86 _key, _ftype, _mimeType];
89 /* first check fixed child classes */
91 if (_folder && !isDir) {
92 factory = [self->classToFileFactory objectForKey:[_folder soClass]];
95 [self debugWithFormat:
96 @"selected a file factory fixed to folderclass: %@", factory];
102 /* then, check exact names (eg 'htpasswd') */
104 if ((factory = [self->nameToFileFactory objectForKey:_key])) {
105 if (factoryDebugOn) {
106 [self debugWithFormat:@"selected file factory by exact name '%@': %@",
112 /* now check extension */
114 pe = [_key pathExtension];
115 if (pe == nil) pe = @"";
117 if ((factory = [self->extToFileFactory objectForKey:pe])) {
118 if (factoryDebugOn) {
119 [self debugWithFormat:@"selected file factory by extension '%@': %@",
125 /* check for SoClass factories */
127 classRegistry = [SoClassRegistry sharedClassRegistry];
129 if ((soClass = [classRegistry soClassForExactName:_key])) {
130 if (factoryDebugOn) {
131 [self debugWithFormat:@"selected SoClass factory by exact name '%@': %@",
135 else if ((soClass = [classRegistry soClassForExtension:pe])) {
136 if (factoryDebugOn) {
137 [self debugWithFormat:@"selected SoClass factory by extension '%@': %@",
143 if ((factory = [soClass ofsObjectFactory]))
146 if (factoryDebugOn) {
147 [self debugWithFormat:
148 @"did not use SoClass for name/extension %@/'%@': %@",
156 return isDir ? self->defaultFolderFactory : self->defaultFileFactory;
159 - (id)restorationFactoryForContext:(OFSFactoryContext *)_ctx {
160 return [self factoryForChildKey:[_ctx nameInContainer]
161 ofFolder:[_ctx container]
162 fileType:_ctx->fileType
163 mimeType:_ctx->mimeType];
165 - (id)creationFactoryForContext:(OFSFactoryContext *)_ctx {
166 return [self factoryForChildKey:[_ctx nameInContainer]
167 ofFolder:[_ctx container]
168 fileType:_ctx->fileType
169 mimeType:_ctx->mimeType];
174 - (void)registerFileFactory:(id)_factory forSoClass:(SoClass *)_clazz {
175 if (_factory == nil) return;
176 if (_clazz == nil) return;
177 if (factoryRegDebugOn) {
178 [self debugWithFormat:@"registering file factory '%@' for class %@",
181 [self->classToFileFactory setObject:_factory forKey:_clazz];
184 - (void)registerFileFactory:(id)_factory forClass:(Class)_clazz {
185 [self registerFileFactory:_factory forSoClass:[_clazz soClass]];
188 - (void)registerFileFactory:(id)_factory forExtension:(NSString *)_ext {
189 if (_factory == nil) return;
190 if (_ext == nil) return;
192 if (factoryRegDebugOn) {
193 [self debugWithFormat:@"registering file factory '%@' for extension %@",
196 [self->extToFileFactory setObject:_factory forKey:_ext];
199 - (void)registerFileFactory:(id)_factory forExactName:(NSString *)_name {
200 if (_factory == nil) return;
201 if (_name == nil) return;
203 if (factoryRegDebugOn) {
204 [self debugWithFormat:@"registering file factory '%@' for exact name '%@'",
207 [self->nameToFileFactory setObject:_factory forKey:_name];
210 @end /* OFSFactoryRegistry */
212 @implementation SoClass(Factory)
214 - (id)ofsObjectFactory {
218 @end /* SoClass(Factory) */
220 @implementation SoObjCClass(Factory)
222 - (id)ofsObjectFactory {
225 if ((bClazz = [self objcClass]) == Nil)
228 if (![bClazz respondsToSelector:@selector(instantiateInFactoryContext:)])
234 @end /* SoObjCClass(Factory) */