]> err.no Git - sope/blob - sope-core/NGExtensions/NGCustomFileManager.m
new aggregate Xcode with proper dependencies, removed old Xcode projects
[sope] / sope-core / NGExtensions / NGCustomFileManager.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
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 <NGExtensions/NGCustomFileManager.h>
24 #include "common.h"
25
26 typedef struct {
27   NSString                *sourcePath;
28   NSString                *absolutePath;
29   NSString                *path;
30   NGCustomFileManagerInfo *info;
31   id                      fileManager;
32 } NGCustomFMPath;
33
34 @interface NGCustomFileManager(Helpers)
35 - (NGCustomFMPath)_resolvePath:(NSString *)_path;
36 - (BOOL)_boolDo:(SEL)_sel onPath:(NSString *)_path;
37 - (BOOL)_boolDo:(SEL)_sel onPath:(NSString *)_path handler:(id)_handler;
38 - (id)_do:(SEL)_sel onPath:(NSString *)_path;
39 @end
40
41 @implementation NGCustomFileManager
42
43 + (int)version {
44   return [super version] + 0 /* v0 */;
45 }
46 + (void)initialize {
47   NSAssert2([super version] == 0,
48             @"invalid superclass (%@) version %i !",
49             NSStringFromClass([self superclass]), [super version]);
50 }
51
52 /* customization */
53
54 - (NSString *)makeAbsolutePath:(NSString *)_path {
55   if ([_path isAbsolutePath])
56     return _path;
57   
58   return [[self currentDirectoryPath] stringByAppendingPathComponent:_path];
59 }
60
61 - (NGCustomFileManagerInfo *)fileManagerInfoForPath:(NSString *)_path {
62   return nil;
63 }
64
65 /* common ops */
66
67 - (NGCustomFMPath)_resolvePath:(NSString *)_path {
68   NGCustomFMPath p;
69   
70   p.sourcePath   = _path;
71   p.absolutePath = [self makeAbsolutePath:_path];
72   p.info         = [self fileManagerInfoForPath:_path];
73   p.path         = [p.info rewriteAbsolutePath:p.absolutePath];
74   p.fileManager  = [p.info fileManager];
75   return p;
76 }
77
78 - (BOOL)_boolDo:(SEL)_sel onPath:(NSString *)_path {
79   NGCustomFMPath p;
80   BOOL (*op)(id,SEL,NSString *);
81   
82   if (_sel == NULL) return NO;
83   p = [self _resolvePath:_path];
84   if ((_path = p.path) == nil) return NO;
85   if ((op = (void *)[p.fileManager methodForSelector:_sel]) == NULL) return NO;
86   
87   return op(p.fileManager, _sel, _path);
88 }
89 - (BOOL)_boolDo:(SEL)_sel onPath:(NSString *)_path handler:(id)_handler {
90   NGCustomFMPath p;
91   BOOL (*op)(id,SEL,NSString *,id);
92   
93   if (_sel == NULL) return NO;
94   p = [self _resolvePath:_path];
95   if ((_path = p.path) == nil) return NO;
96   if ((op = (void *)[p.fileManager methodForSelector:_sel]) == NULL) return NO;
97   
98   return op(p.fileManager, _sel, _path, _handler);
99 }
100 - (id)_do:(SEL)_sel onPath:(NSString *)_path {
101   NGCustomFMPath p;
102   id (*op)(id,SEL,NSString *);
103   
104   if (_sel == NULL) return NO;
105   p = [self _resolvePath:_path];
106   if ((_path = p.path) == nil) return NO;
107   if ((op = (void *)[p.fileManager methodForSelector:_sel]) == NULL) return NO;
108   
109   return op(p.fileManager, _sel, _path);
110 }
111
112 /* directory operations */
113
114 - (BOOL)changeCurrentDirectoryPath:(NSString *)_path {
115   BOOL isDir = NO;
116   if ((_path = [self makeAbsolutePath:_path]) == nil) return NO;
117   
118   if (![self fileExistsAtPath:_path isDirectory:&isDir]) return NO;
119   if (!isDir) return NO;
120   
121   ASSIGNCOPY(self->cwd, _path);
122   return YES;
123 }
124 - (NSString *)currentDirectoryPath {
125   return self->cwd;
126 }
127
128 - (BOOL)createDirectoryAtPath:(NSString *)_path
129   attributes:(NSDictionary *)_ats
130 {
131   NGCustomFMPath p;
132   p = [self _resolvePath:_path];
133   if (p.path == nil) return NO;
134   
135   return [p.fileManager createDirectoryAtPath:p.path attributes:_ats];
136 }
137
138 /* file operations */
139
140 - (BOOL)copyPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
141   NGCustomFileManagerInfo *sinfo, *dinfo;
142   
143   if ((_s = [self makeAbsolutePath:_s]) == nil) return NO;
144   if ((_d = [self makeAbsolutePath:_d]) == nil) return NO;
145   if ((sinfo = [self fileManagerInfoForPath:_s]) == nil) return NO;
146   if ((dinfo = [self fileManagerInfoForPath:_d]) == nil) return NO;
147   _s = [sinfo rewriteAbsolutePath:_s];
148   _d = [dinfo rewriteAbsolutePath:_d];
149   
150   if ([sinfo isEqual:dinfo]) /* same filemanager */
151     return [[sinfo fileManager] copyPath:_s toPath:_d handler:_handler];
152   
153   /* operation between different filemanagers ... */
154   return NO;
155 }
156
157 - (BOOL)movePath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
158   NGCustomFileManagerInfo *sinfo, *dinfo;
159   
160   if ((_s = [self makeAbsolutePath:_s]) == nil) return NO;
161   if ((_d = [self makeAbsolutePath:_d]) == nil) return NO;
162   if ((sinfo = [self fileManagerInfoForPath:_s]) == nil) return NO;
163   if ((dinfo = [self fileManagerInfoForPath:_d]) == nil) return NO;
164   _s = [sinfo rewriteAbsolutePath:_s];
165   _d = [dinfo rewriteAbsolutePath:_d];
166   
167   if ([sinfo isEqual:dinfo]) /* same filemanager */
168     return [[sinfo fileManager] movePath:_s toPath:_d handler:_handler];
169     
170   /* operation between different filemanagers ... */
171   return NO;
172 }
173
174 - (BOOL)linkPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
175   NGCustomFileManagerInfo *sinfo, *dinfo;
176   
177   if ((_s = [self makeAbsolutePath:_s]) == nil) return NO;
178   if ((_d = [self makeAbsolutePath:_d]) == nil) return NO;
179   if ((sinfo = [self fileManagerInfoForPath:_s]) == nil) return NO;
180   if ((dinfo = [self fileManagerInfoForPath:_d]) == nil) return NO;
181   _s = [sinfo rewriteAbsolutePath:_s];
182   _d = [dinfo rewriteAbsolutePath:_d];
183   
184   if ([sinfo isEqual:dinfo]) /* same filemanager */
185     return [[sinfo fileManager] linkPath:_s toPath:_d handler:_handler];
186     
187   /* operation between different filemanagers ... */
188   return NO;
189 }
190
191 - (BOOL)removeFileAtPath:(NSString *)_path handler:(id)_handler {
192   return [self _boolDo:_cmd onPath:_path handler:_handler];
193 }
194
195 - (BOOL)createFileAtPath:(NSString *)_path contents:(NSData *)_contents
196   attributes:(NSDictionary *)_attributes
197 {
198   NGCustomFMPath p;
199   p = [self _resolvePath:_path];
200   if (p.path == nil) return NO;
201   
202   return [p.fileManager
203                 createFileAtPath:p.path
204                 contents:_contents
205                 attributes:_attributes];
206 }
207
208 /* getting and comparing file contents */
209
210 - (NSData *)contentsAtPath:(NSString *)_path {
211   return [self _do:_cmd onPath:_path];
212 }
213
214 - (BOOL)contentsEqualAtPath:(NSString *)_path1 andPath:(NSString *)_path2 {
215   NGCustomFileManagerInfo *info1, *info2;
216   
217   if ((_path1 = [self makeAbsolutePath:_path1]) == nil) return NO;
218   if ((_path2 = [self makeAbsolutePath:_path2]) == nil) return NO;
219   if ((info1 = [self fileManagerInfoForPath:_path1]) == nil) return NO;
220   if ((info2 = [self fileManagerInfoForPath:_path2]) == nil) return NO;
221   _path1 = [info1 rewriteAbsolutePath:_path1];
222   _path2 = [info2 rewriteAbsolutePath:_path2];
223   
224   if ([info1 isEqual:info2]) /* same filemanager */
225     return [[info1 fileManager] contentsEqualAtPath:_path1 andPath:_path2];
226   
227   /* operation between different filemanagers ... */
228   return NO;
229 }
230
231 /* determining access to files */
232
233 - (BOOL)fileExistsAtPath:(NSString *)_path {
234   return [self _boolDo:_cmd onPath:_path];
235 }
236 - (BOOL)fileExistsAtPath:(NSString *)_path isDirectory:(BOOL *)_isDirectory {
237   NGCustomFMPath p;
238   p = [self _resolvePath:_path];
239   if (p.path == nil) return NO;
240   
241   return [p.fileManager fileExistsAtPath:p.path isDirectory:_isDirectory];
242 }
243 - (BOOL)isReadableFileAtPath:(NSString *)_path {
244   return [self _boolDo:_cmd onPath:_path];
245 }
246 - (BOOL)isWritableFileAtPath:(NSString *)_path {
247   return [self _boolDo:_cmd onPath:_path];
248 }
249 - (BOOL)isExecutableFileAtPath:(NSString *)_path {
250   return [self _boolDo:_cmd onPath:_path];
251 }
252 - (BOOL)isDeletableFileAtPath:(NSString *)_path {
253   return [self _boolDo:_cmd onPath:_path];
254 }
255
256 /* Getting and setting attributes */
257
258 - (NSDictionary *)fileAttributesAtPath:(NSString *)_p traverseLink:(BOOL)_flag{
259   NGCustomFMPath p;
260   p = [self _resolvePath:_p];
261   if (p.path == nil) return NO;
262   
263   /* special link handling required ??? */
264   return [p.fileManager fileAttributesAtPath:p.path traverseLink:_flag];
265 }
266
267 - (NSDictionary *)fileSystemAttributesAtPath:(NSString *)_p {
268   return [self _do:_cmd onPath:_p];
269 }
270
271 - (BOOL)changeFileAttributes:(NSDictionary *)_attributes atPath:(NSString *)_p{
272   NGCustomFMPath p;
273   p = [self _resolvePath:_p];
274   if (p.path == nil) return NO;
275   
276   return [p.fileManager changeFileAttributes:_attributes atPath:p.path];
277 }
278
279 /* discovering directory contents */
280
281 - (NSArray *)directoryContentsAtPath:(NSString *)_path {
282   /* this returns relative path's, can be passed back */
283   return [self _do:_cmd onPath:_path];
284 }
285
286 - (NSDirectoryEnumerator *)enumeratorAtPath:(NSString *)_path {
287   /* this needs to be wrapped ! */
288   return nil;
289 }
290
291 - (NSArray *)subpathsAtPath:(NSString *)_path {
292   /* this returns relative path's, can be passed back */
293   return [self _do:_cmd onPath:_path];
294 }
295
296 /* symbolic-link operations */
297
298 - (BOOL)createSymbolicLinkAtPath:(NSString *)_p pathContent:(NSString *)_dpath{
299   /* should that process the link-path somehow ??? */
300   NGCustomFMPath p;
301   p = [self _resolvePath:_p];
302   if (p.path == nil) return NO;
303   
304   return [p.fileManager createSymbolicLinkAtPath:p.path pathContent:_dpath];
305 }
306 - (NSString *)pathContentOfSymbolicLinkAtPath:(NSString *)_path {
307   /* should that process the link-path somehow ??? */
308   return [self _do:_cmd onPath:_path];
309 }
310
311 /* feature check */
312
313 - (BOOL)supportsVersioningAtPath:(NSString *)_path {
314   return [self _boolDo:_cmd onPath:_path];
315 }
316 - (BOOL)supportsLockingAtPath:(NSString *)_path {
317   return [self _boolDo:_cmd onPath:_path];
318 }
319 - (BOOL)supportsFolderDataSourceAtPath:(NSString *)_path {
320   return [self _boolDo:_cmd onPath:_path];
321 }
322
323 - (BOOL)supportsFeature:(NSString *)_featureURI atPath:(NSString *)_path {
324   NGCustomFMPath p;
325   p = [self _resolvePath:_path];
326   if (p.path == nil) return NO;
327   
328   return [p.fileManager supportsFeature:_featureURI atPath:p.path];
329 }
330
331 /* writing */
332
333 - (BOOL)writeContents:(NSData *)_content atPath:(NSString *)_path {
334   NGCustomFMPath p;
335   p = [self _resolvePath:_path];
336   if (p.path == nil) return NO;
337   
338   return [p.fileManager writeContents:_content atPath:p.path];
339 }
340
341 /* global-IDs */
342
343 - (EOGlobalID *)globalIDForPath:(NSString *)_path {
344   NGCustomFileManagerInfo *info;
345   if ((_path = [self makeAbsolutePath:_path])      == nil) return NO;
346   if ((info = [self fileManagerInfoForPath:_path]) == nil) return NO;
347
348   if (![info supportsGlobalIDs])
349     return nil;
350   
351   if ((_path = [info rewriteAbsolutePath:_path]) == nil)
352     return NO;
353   
354   return [[info fileManager] globalIDForPath:_path];
355 }
356
357 - (NSString *)pathForGlobalID:(EOGlobalID *)_gid {
358   return nil;
359 }
360
361 /* trash */
362
363 - (BOOL)supportsTrashFolderAtPath:(NSString *)_path {
364   return [self _boolDo:_cmd onPath:_path];
365 }
366 - (NSString *)trashFolderForPath:(NSString *)_path {
367   return NO;
368 }
369
370 @end /* NGCustomFileManager */
371
372 @implementation NGCustomFileManager(NGFileManagerVersioning)
373
374 /* versioning */
375
376 - (BOOL)checkoutFileAtPath:(NSString *)_path handler:(id)_handler {
377   return [self _boolDo:_cmd onPath:_path handler:_handler];
378 }
379 - (BOOL)releaseFileAtPath:(NSString *)_path handler:(id)_handler {
380   return [self _boolDo:_cmd onPath:_path handler:_handler];
381 }
382 - (BOOL)rejectFileAtPath:(NSString *)_path handler:(id)_handler {
383   return [self _boolDo:_cmd onPath:_path handler:_handler];
384 }
385 - (BOOL)checkoutFileAtPath:(NSString *)_path version:(NSString *)_version
386   handler:(id)_handler
387 {
388   NGCustomFMPath p;
389   p = [self _resolvePath:_path];
390   if (p.path == nil) return NO;
391   
392   return [p.fileManager
393            checkoutFileAtPath:p.path version:_version handler:_handler];
394 }
395
396 /* versioning data */
397
398 - (NSString *)lastVersionAtPath:(NSString *)_path {
399   return [self _do:_cmd onPath:_path];
400 }
401 - (NSArray *)versionsAtPath:(NSString *)_path {
402   return [self _do:_cmd onPath:_path];
403 }
404
405 - (NSData *)contentsAtPath:(NSString *)_path version:(NSString *)_version {
406   NGCustomFMPath p;
407   p = [self _resolvePath:_path];
408   if (p.path == nil) return NO;
409   
410   return [p.fileManager contentsAtPath:p.path version:_version];
411 }
412
413 - (NSDictionary *)fileAttributesAtPath:(NSString *)_path
414   traverseLink:(BOOL)_followLink
415   version:(NSString *)_version
416 {
417   NGCustomFMPath p;
418   p = [self _resolvePath:_path];
419   if (p.path == nil) return NO;
420   
421   /* do something special to symlink ??? */
422   
423   return [p.fileManager
424            fileAttributesAtPath:p.path
425            traverseLink:_followLink
426            version:_version];
427 }
428
429 @end /* NGCustomFileManager(NGFileManagerVersioning) */
430
431 @implementation NGCustomFileManager(NGFileManagerLocking)
432
433 - (BOOL)lockFileAtPath:(NSString *)_path handler:(id)_handler {
434   return [self _boolDo:_cmd onPath:_path handler:_handler];
435 }
436 - (BOOL)unlockFileAtPath:(NSString *)_path handler:(id)_handler {
437   return [self _boolDo:_cmd onPath:_path handler:_handler];
438 }
439 - (BOOL)isFileLockedAtPath:(NSString *)_path {
440   return [self _boolDo:_cmd onPath:_path];
441 }
442
443 /* access rights */
444
445 - (BOOL)isLockableFileAtPath:(NSString *)_path {
446   return [self _boolDo:_cmd onPath:_path];
447 }
448 - (BOOL)isUnlockableFileAtPath:(NSString *)_path {
449   return [self _boolDo:_cmd onPath:_path];
450 }
451
452 @end /* NGCustomFileManager(NGFileManagerLocking) */
453
454 @implementation NGCustomFileManager(NGFileManagerDataSources)
455
456 /* datasources (work on folders) */
457
458 - (EODataSource *)dataSourceAtPath:(NSString *)_path {
459   return [self _do:_cmd onPath:_path];
460 }
461
462 - (EODataSource *)dataSource {
463   return [self dataSourceAtPath:[self currentDirectoryPath]];
464 }
465
466 @end /* NGCustomFileManager(NGFileManagerDataSources) */
467
468 @implementation NGCustomFileManagerInfo
469
470 - (id)initWithCustomFileManager:(NGCustomFileManager *)_master
471   fileManager:(id<NGFileManager,NSObject>)_fm
472 {
473   self->master      = _master;
474   self->fileManager = [_fm retain];
475   return self;
476 }
477 - (id)init {
478   return [self initWithCustomFileManager:nil fileManager:nil];
479 }
480
481 - (void)dealloc {
482   [self->fileManager release];
483   [super dealloc];
484 }
485
486 - (void)resetMaster {
487   self->master = nil;
488 }
489
490 /* accessors */
491
492 - (NGCustomFileManager *)master {
493   return self->master;
494 }
495 - (id<NGFileManager,NSObject>)fileManager {
496   return self->fileManager;
497 }
498
499 /* operations */
500
501 - (NSString *)rewriteAbsolutePath:(NSString *)_path {
502   return _path;
503 }
504
505 /* capabilities */
506
507 - (BOOL)supportsGlobalIDs {
508   return [self->fileManager respondsToSelector:@selector(globalIDForPath:)];
509 }
510
511 @end /* NGCustomFileManagerInfo */