2 Copyright (C) 2002-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE 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 SOPE 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 SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "OFSFactoryRegistry.h"
23 #include "OFSFolder.h"
25 #include "OFSFactoryContext.h"
26 #include "SoClassRegistry.h"
27 #include "SoObjCClass.h"
30 @interface SoClass(Factory)
31 - (id)ofsObjectFactory;
34 @implementation OFSFactoryRegistry
36 static int factoryDebugOn = 0;
37 static int factoryRegDebugOn = 0;
39 + (id)sharedFactoryRegistry {
41 if (reg == nil) reg = [[OFSFactoryRegistry alloc] init];
46 if ((self = [super init])) {
47 self->classToFileFactory =
48 [[NSMutableDictionary alloc] initWithCapacity:32];
49 self->extToFileFactory =
50 [[NSMutableDictionary alloc] initWithCapacity:64];
51 self->nameToFileFactory =
52 [[NSMutableDictionary alloc] initWithCapacity:64];
54 self->defaultFolderFactory = [OFSFolder class];
55 self->defaultFileFactory = [OFSFile class];
60 [self->defaultFileFactory release];
61 [self->defaultFolderFactory release];
62 [self->classToFileFactory release];
63 [self->extToFileFactory release];
64 [self->nameToFileFactory release];
70 - (id)factoryForChildKey:(NSString *)_key
71 ofFolder:(OFSFolder *)_folder
72 fileType:(NSString *)_ftype
73 mimeType:(NSString *)_mimeType
75 SoClassRegistry *classRegistry;
81 isDir = [_ftype isEqualToString:NSFileTypeDirectory] ? YES : NO;
84 [self debugWithFormat:@"lookup factory for key %@ type=%@ mime=%@",
85 _key, _ftype, _mimeType];
88 /* first check fixed child classes */
90 if (_folder && !isDir) {
91 factory = [self->classToFileFactory objectForKey:[_folder soClass]];
94 [self debugWithFormat:
95 @"selected a file factory fixed to folderclass: %@", factory];
101 /* then, check exact names (eg 'htpasswd') */
103 if ((factory = [self->nameToFileFactory objectForKey:_key])) {
104 if (factoryDebugOn) {
105 [self debugWithFormat:@"selected file factory by exact name '%@': %@",
111 /* now check extension */
113 pe = [_key pathExtension];
114 if (pe == nil) pe = @"";
116 if ((factory = [self->extToFileFactory objectForKey:pe])) {
117 if (factoryDebugOn) {
118 [self debugWithFormat:@"selected file factory by extension '%@': %@",
124 /* check for SoClass factories */
126 classRegistry = [SoClassRegistry sharedClassRegistry];
128 if ((soClass = [classRegistry soClassForExactName:_key])) {
129 if (factoryDebugOn) {
130 [self debugWithFormat:@"selected SoClass factory by exact name '%@': %@",
134 else if ((soClass = [classRegistry soClassForExtension:pe])) {
135 if (factoryDebugOn) {
136 [self debugWithFormat:@"selected SoClass factory by extension '%@': %@",
142 if ((factory = [soClass ofsObjectFactory]))
145 if (factoryDebugOn) {
146 [self debugWithFormat:
147 @"did not use SoClass for name/extension %@/'%@': %@",
155 return isDir ? self->defaultFolderFactory : self->defaultFileFactory;
158 - (id)restorationFactoryForContext:(OFSFactoryContext *)_ctx {
159 return [self factoryForChildKey:[_ctx nameInContainer]
160 ofFolder:[_ctx container]
161 fileType:_ctx->fileType
162 mimeType:_ctx->mimeType];
164 - (id)creationFactoryForContext:(OFSFactoryContext *)_ctx {
165 return [self factoryForChildKey:[_ctx nameInContainer]
166 ofFolder:[_ctx container]
167 fileType:_ctx->fileType
168 mimeType:_ctx->mimeType];
173 - (void)registerFileFactory:(id)_factory forSoClass:(SoClass *)_clazz {
174 if (_factory == nil) return;
175 if (_clazz == nil) return;
176 if (factoryRegDebugOn) {
177 [self debugWithFormat:@"registering file factory '%@' for class %@",
180 [self->classToFileFactory setObject:_factory forKey:_clazz];
183 - (void)registerFileFactory:(id)_factory forClass:(Class)_clazz {
184 [self registerFileFactory:_factory forSoClass:[_clazz soClass]];
187 - (void)registerFileFactory:(id)_factory forExtension:(NSString *)_ext {
188 if (_factory == nil) return;
189 if (_ext == nil) return;
191 if (factoryRegDebugOn) {
192 [self debugWithFormat:@"registering file factory '%@' for extension %@",
195 [self->extToFileFactory setObject:_factory forKey:_ext];
198 - (void)registerFileFactory:(id)_factory forExactName:(NSString *)_name {
199 if (_factory == nil) return;
200 if (_name == nil) return;
202 if (factoryRegDebugOn) {
203 [self debugWithFormat:@"registering file factory '%@' for exact name '%@'",
206 [self->nameToFileFactory setObject:_factory forKey:_name];
209 @end /* OFSFactoryRegistry */
211 @implementation SoClass(Factory)
213 - (id)ofsObjectFactory {
217 @end /* SoClass(Factory) */
219 @implementation SoObjCClass(Factory)
221 - (id)ofsObjectFactory {
224 if ((bClazz = [self objcClass]) == Nil)
227 if (![bClazz respondsToSelector:@selector(instantiateInFactoryContext:)])
233 @end /* SoObjCClass(Factory) */