]> err.no Git - sope/blob - sope-appserver/NGObjWeb/SoOFS/OFSFactoryRegistry.m
renamed packages as discussed in the developer list
[sope] / sope-appserver / NGObjWeb / SoOFS / OFSFactoryRegistry.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "OFSFactoryRegistry.h"
24 #include "OFSFolder.h"
25 #include "OFSFile.h"
26 #include "OFSFactoryContext.h"
27 #include "SoClassRegistry.h"
28 #include "SoObjCClass.h"
29 #include "common.h"
30
31 @interface SoClass(Factory)
32 - (id)ofsObjectFactory;
33 @end
34
35 @implementation OFSFactoryRegistry
36
37 static int factoryDebugOn    = 0;
38 static int factoryRegDebugOn = 0;
39
40 + (id)sharedFactoryRegistry {
41   static id reg = nil;
42   if (reg == nil) reg = [[OFSFactoryRegistry alloc] init];
43   return reg;
44 }
45
46 - (id)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];
54     
55     self->defaultFolderFactory = [OFSFolder class];
56     self->defaultFileFactory   = [OFSFile   class];
57   }
58   return self;
59 }
60 - (void)dealloc {
61   [self->defaultFileFactory   release];
62   [self->defaultFolderFactory release];
63   [self->classToFileFactory   release];
64   [self->extToFileFactory     release];
65   [self->nameToFileFactory    release];
66   [super dealloc];
67 }
68
69 /* lookup factory */
70
71 - (id)factoryForChildKey:(NSString *)_key 
72   ofFolder:(OFSFolder *)_folder
73   fileType:(NSString *)_ftype
74   mimeType:(NSString *)_mimeType
75 {
76   SoClassRegistry *classRegistry;
77   NSString *pe;
78   SoClass  *soClass;
79   BOOL     isDir;
80   id       factory = nil;
81   
82   isDir = [_ftype isEqualToString:NSFileTypeDirectory] ? YES : NO;
83   
84   if (factoryDebugOn) {
85     [self debugWithFormat:@"lookup factory for key %@ type=%@ mime=%@",
86             _key, _ftype, _mimeType];
87   }
88   
89   /* first check fixed child classes */
90   
91   if (_folder && !isDir) {
92     factory = [self->classToFileFactory objectForKey:[_folder soClass]];
93     if (factory) {
94       if (factoryDebugOn) {
95         [self debugWithFormat:
96                 @"selected a file factory fixed to folderclass: %@", factory];
97       }
98       return factory;
99     }
100   }
101   
102   /* then, check exact names (eg 'htpasswd') */
103
104   if ((factory = [self->nameToFileFactory objectForKey:_key])) {
105     if (factoryDebugOn) {
106       [self debugWithFormat:@"selected file factory by exact name '%@': %@",
107               _key, factory];
108     }
109     return factory;
110   }
111   
112   /* now check extension */
113   
114   pe = [_key pathExtension];
115   if (pe == nil) pe = @"";
116   
117   if ((factory = [self->extToFileFactory objectForKey:pe])) {
118     if (factoryDebugOn) {
119       [self debugWithFormat:@"selected file factory by extension '%@': %@",
120               pe, factory];
121     }
122     return factory;
123   }
124   
125   /* check for SoClass factories */
126
127   classRegistry = [SoClassRegistry sharedClassRegistry];
128   
129   if ((soClass = [classRegistry soClassForExactName:_key])) {
130     if (factoryDebugOn) {
131       [self debugWithFormat:@"selected SoClass factory by exact name '%@': %@",
132               _key, factory];
133     }
134   }
135   else if ((soClass = [classRegistry soClassForExtension:pe])) {
136     if (factoryDebugOn) {
137       [self debugWithFormat:@"selected SoClass factory by extension '%@': %@",
138               pe, factory];
139     }
140   }
141   
142   if (soClass) {
143     if ((factory = [soClass ofsObjectFactory]))
144       return factory;
145     else {
146       if (factoryDebugOn) {
147         [self debugWithFormat:
148                 @"did not use SoClass for name/extension %@/'%@': %@",
149                 _key, pe, soClass];
150       }
151     }
152   }
153   
154   /* apply defaults */
155   
156   return isDir ? self->defaultFolderFactory : self->defaultFileFactory;
157 }
158
159 - (id)restorationFactoryForContext:(OFSFactoryContext *)_ctx {
160   return [self factoryForChildKey:[_ctx nameInContainer]
161                ofFolder:[_ctx container]
162                fileType:_ctx->fileType
163                mimeType:_ctx->mimeType];
164 }
165 - (id)creationFactoryForContext:(OFSFactoryContext *)_ctx {
166   return [self factoryForChildKey:[_ctx nameInContainer]
167                ofFolder:[_ctx container]
168                fileType:_ctx->fileType
169                mimeType:_ctx->mimeType];
170 }
171
172 /* registration */
173
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 %@",
179             _factory, _clazz];
180   }
181   [self->classToFileFactory setObject:_factory forKey:_clazz];
182 }
183
184 - (void)registerFileFactory:(id)_factory forClass:(Class)_clazz {
185   [self registerFileFactory:_factory forSoClass:[_clazz soClass]];
186 }
187
188 - (void)registerFileFactory:(id)_factory forExtension:(NSString *)_ext {
189   if (_factory == nil) return;
190   if (_ext     == nil) return;
191   
192   if (factoryRegDebugOn) {
193     [self debugWithFormat:@"registering file factory '%@' for extension %@",
194             _factory, _ext];
195   }
196   [self->extToFileFactory setObject:_factory forKey:_ext];
197 }
198
199 - (void)registerFileFactory:(id)_factory forExactName:(NSString *)_name {
200   if (_factory == nil) return;
201   if (_name    == nil) return;
202   
203   if (factoryRegDebugOn) {
204     [self debugWithFormat:@"registering file factory '%@' for exact name '%@'",
205             _factory, _name];
206   }
207   [self->nameToFileFactory setObject:_factory forKey:_name];
208 }
209
210 @end /* OFSFactoryRegistry */
211
212 @implementation SoClass(Factory)
213
214 - (id)ofsObjectFactory {
215   return nil;
216 }
217
218 @end /* SoClass(Factory) */
219
220 @implementation SoObjCClass(Factory)
221
222 - (id)ofsObjectFactory {
223   Class bClazz;
224   
225   if ((bClazz = [self objcClass]) == Nil)
226     return nil;
227   
228   if (![bClazz respondsToSelector:@selector(instantiateInFactoryContext:)])
229     return nil;
230   
231   return bClazz;
232 }
233
234 @end /* SoObjCClass(Factory) */