2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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 <NGExtensions/NGCustomFileManager.h>
28 NSString *absolutePath;
30 NGCustomFileManagerInfo *info;
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;
41 @implementation NGCustomFileManager
44 return [super version] + 0 /* v0 */;
47 NSAssert2([super version] == 0,
48 @"invalid superclass (%@) version %i !",
49 NSStringFromClass([self superclass]), [super version]);
54 - (NSString *)makeAbsolutePath:(NSString *)_path {
55 if ([_path isAbsolutePath])
58 return [[self currentDirectoryPath] stringByAppendingPathComponent:_path];
61 - (NGCustomFileManagerInfo *)fileManagerInfoForPath:(NSString *)_path {
67 - (NGCustomFMPath)_resolvePath:(NSString *)_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];
78 - (BOOL)_boolDo:(SEL)_sel onPath:(NSString *)_path {
80 BOOL (*op)(id,SEL,NSString *);
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;
87 return op(p.fileManager, _sel, _path);
89 - (BOOL)_boolDo:(SEL)_sel onPath:(NSString *)_path handler:(id)_handler {
91 BOOL (*op)(id,SEL,NSString *,id);
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;
98 return op(p.fileManager, _sel, _path, _handler);
100 - (id)_do:(SEL)_sel onPath:(NSString *)_path {
102 id (*op)(id,SEL,NSString *);
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;
109 return op(p.fileManager, _sel, _path);
112 /* directory operations */
114 - (BOOL)changeCurrentDirectoryPath:(NSString *)_path {
116 if ((_path = [self makeAbsolutePath:_path]) == nil) return NO;
118 if (![self fileExistsAtPath:_path isDirectory:&isDir]) return NO;
119 if (!isDir) return NO;
121 ASSIGNCOPY(self->cwd, _path);
124 - (NSString *)currentDirectoryPath {
128 - (BOOL)createDirectoryAtPath:(NSString *)_path
129 attributes:(NSDictionary *)_ats
132 p = [self _resolvePath:_path];
133 if (p.path == nil) return NO;
135 return [p.fileManager createDirectoryAtPath:p.path attributes:_ats];
138 /* file operations */
140 - (BOOL)copyPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
141 NGCustomFileManagerInfo *sinfo, *dinfo;
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];
150 if ([sinfo isEqual:dinfo]) /* same filemanager */
151 return [[sinfo fileManager] copyPath:_s toPath:_d handler:_handler];
153 /* operation between different filemanagers ... */
157 - (BOOL)movePath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
158 NGCustomFileManagerInfo *sinfo, *dinfo;
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];
167 if ([sinfo isEqual:dinfo]) /* same filemanager */
168 return [[sinfo fileManager] movePath:_s toPath:_d handler:_handler];
170 /* operation between different filemanagers ... */
174 - (BOOL)linkPath:(NSString *)_s toPath:(NSString *)_d handler:(id)_handler {
175 NGCustomFileManagerInfo *sinfo, *dinfo;
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];
184 if ([sinfo isEqual:dinfo]) /* same filemanager */
185 return [[sinfo fileManager] linkPath:_s toPath:_d handler:_handler];
187 /* operation between different filemanagers ... */
191 - (BOOL)removeFileAtPath:(NSString *)_path handler:(id)_handler {
192 return [self _boolDo:_cmd onPath:_path handler:_handler];
195 - (BOOL)createFileAtPath:(NSString *)_path contents:(NSData *)_contents
196 attributes:(NSDictionary *)_attributes
199 p = [self _resolvePath:_path];
200 if (p.path == nil) return NO;
202 return [p.fileManager
203 createFileAtPath:p.path
205 attributes:_attributes];
208 /* getting and comparing file contents */
210 - (NSData *)contentsAtPath:(NSString *)_path {
211 return [self _do:_cmd onPath:_path];
214 - (BOOL)contentsEqualAtPath:(NSString *)_path1 andPath:(NSString *)_path2 {
215 NGCustomFileManagerInfo *info1, *info2;
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];
224 if ([info1 isEqual:info2]) /* same filemanager */
225 return [[info1 fileManager] contentsEqualAtPath:_path1 andPath:_path2];
227 /* operation between different filemanagers ... */
231 /* determining access to files */
233 - (BOOL)fileExistsAtPath:(NSString *)_path {
234 return [self _boolDo:_cmd onPath:_path];
236 - (BOOL)fileExistsAtPath:(NSString *)_path isDirectory:(BOOL *)_isDirectory {
238 p = [self _resolvePath:_path];
239 if (p.path == nil) return NO;
241 return [p.fileManager fileExistsAtPath:p.path isDirectory:_isDirectory];
243 - (BOOL)isReadableFileAtPath:(NSString *)_path {
244 return [self _boolDo:_cmd onPath:_path];
246 - (BOOL)isWritableFileAtPath:(NSString *)_path {
247 return [self _boolDo:_cmd onPath:_path];
249 - (BOOL)isExecutableFileAtPath:(NSString *)_path {
250 return [self _boolDo:_cmd onPath:_path];
252 - (BOOL)isDeletableFileAtPath:(NSString *)_path {
253 return [self _boolDo:_cmd onPath:_path];
256 /* Getting and setting attributes */
258 - (NSDictionary *)fileAttributesAtPath:(NSString *)_p traverseLink:(BOOL)_flag{
260 p = [self _resolvePath:_p];
261 if (p.path == nil) return NO;
263 /* special link handling required ??? */
264 return [p.fileManager fileAttributesAtPath:p.path traverseLink:_flag];
267 - (NSDictionary *)fileSystemAttributesAtPath:(NSString *)_p {
268 return [self _do:_cmd onPath:_p];
271 - (BOOL)changeFileAttributes:(NSDictionary *)_attributes atPath:(NSString *)_p{
273 p = [self _resolvePath:_p];
274 if (p.path == nil) return NO;
276 return [p.fileManager changeFileAttributes:_attributes atPath:p.path];
279 /* discovering directory contents */
281 - (NSArray *)directoryContentsAtPath:(NSString *)_path {
282 /* this returns relative path's, can be passed back */
283 return [self _do:_cmd onPath:_path];
286 - (NSDirectoryEnumerator *)enumeratorAtPath:(NSString *)_path {
287 /* this needs to be wrapped ! */
291 - (NSArray *)subpathsAtPath:(NSString *)_path {
292 /* this returns relative path's, can be passed back */
293 return [self _do:_cmd onPath:_path];
296 /* symbolic-link operations */
298 - (BOOL)createSymbolicLinkAtPath:(NSString *)_p pathContent:(NSString *)_dpath{
299 /* should that process the link-path somehow ??? */
301 p = [self _resolvePath:_p];
302 if (p.path == nil) return NO;
304 return [p.fileManager createSymbolicLinkAtPath:p.path pathContent:_dpath];
306 - (NSString *)pathContentOfSymbolicLinkAtPath:(NSString *)_path {
307 /* should that process the link-path somehow ??? */
308 return [self _do:_cmd onPath:_path];
313 - (BOOL)supportsVersioningAtPath:(NSString *)_path {
314 return [self _boolDo:_cmd onPath:_path];
316 - (BOOL)supportsLockingAtPath:(NSString *)_path {
317 return [self _boolDo:_cmd onPath:_path];
319 - (BOOL)supportsFolderDataSourceAtPath:(NSString *)_path {
320 return [self _boolDo:_cmd onPath:_path];
323 - (BOOL)supportsFeature:(NSString *)_featureURI atPath:(NSString *)_path {
325 p = [self _resolvePath:_path];
326 if (p.path == nil) return NO;
328 return [p.fileManager supportsFeature:_featureURI atPath:p.path];
333 - (BOOL)writeContents:(NSData *)_content atPath:(NSString *)_path {
335 p = [self _resolvePath:_path];
336 if (p.path == nil) return NO;
338 return [p.fileManager writeContents:_content atPath:p.path];
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;
348 if (![info supportsGlobalIDs])
351 if ((_path = [info rewriteAbsolutePath:_path]) == nil)
354 return [[info fileManager] globalIDForPath:_path];
357 - (NSString *)pathForGlobalID:(EOGlobalID *)_gid {
363 - (BOOL)supportsTrashFolderAtPath:(NSString *)_path {
364 return [self _boolDo:_cmd onPath:_path];
366 - (NSString *)trashFolderForPath:(NSString *)_path {
370 @end /* NGCustomFileManager */
372 @implementation NGCustomFileManager(NGFileManagerVersioning)
376 - (BOOL)checkoutFileAtPath:(NSString *)_path handler:(id)_handler {
377 return [self _boolDo:_cmd onPath:_path handler:_handler];
379 - (BOOL)releaseFileAtPath:(NSString *)_path handler:(id)_handler {
380 return [self _boolDo:_cmd onPath:_path handler:_handler];
382 - (BOOL)rejectFileAtPath:(NSString *)_path handler:(id)_handler {
383 return [self _boolDo:_cmd onPath:_path handler:_handler];
385 - (BOOL)checkoutFileAtPath:(NSString *)_path version:(NSString *)_version
389 p = [self _resolvePath:_path];
390 if (p.path == nil) return NO;
392 return [p.fileManager
393 checkoutFileAtPath:p.path version:_version handler:_handler];
396 /* versioning data */
398 - (NSString *)lastVersionAtPath:(NSString *)_path {
399 return [self _do:_cmd onPath:_path];
401 - (NSArray *)versionsAtPath:(NSString *)_path {
402 return [self _do:_cmd onPath:_path];
405 - (NSData *)contentsAtPath:(NSString *)_path version:(NSString *)_version {
407 p = [self _resolvePath:_path];
408 if (p.path == nil) return NO;
410 return [p.fileManager contentsAtPath:p.path version:_version];
413 - (NSDictionary *)fileAttributesAtPath:(NSString *)_path
414 traverseLink:(BOOL)_followLink
415 version:(NSString *)_version
418 p = [self _resolvePath:_path];
419 if (p.path == nil) return NO;
421 /* do something special to symlink ??? */
423 return [p.fileManager
424 fileAttributesAtPath:p.path
425 traverseLink:_followLink
429 @end /* NGCustomFileManager(NGFileManagerVersioning) */
431 @implementation NGCustomFileManager(NGFileManagerLocking)
433 - (BOOL)lockFileAtPath:(NSString *)_path handler:(id)_handler {
434 return [self _boolDo:_cmd onPath:_path handler:_handler];
436 - (BOOL)unlockFileAtPath:(NSString *)_path handler:(id)_handler {
437 return [self _boolDo:_cmd onPath:_path handler:_handler];
439 - (BOOL)isFileLockedAtPath:(NSString *)_path {
440 return [self _boolDo:_cmd onPath:_path];
445 - (BOOL)isLockableFileAtPath:(NSString *)_path {
446 return [self _boolDo:_cmd onPath:_path];
448 - (BOOL)isUnlockableFileAtPath:(NSString *)_path {
449 return [self _boolDo:_cmd onPath:_path];
452 @end /* NGCustomFileManager(NGFileManagerLocking) */
454 @implementation NGCustomFileManager(NGFileManagerDataSources)
456 /* datasources (work on folders) */
458 - (EODataSource *)dataSourceAtPath:(NSString *)_path {
459 return [self _do:_cmd onPath:_path];
462 - (EODataSource *)dataSource {
463 return [self dataSourceAtPath:[self currentDirectoryPath]];
466 @end /* NGCustomFileManager(NGFileManagerDataSources) */
468 @implementation NGCustomFileManagerInfo
470 - (id)initWithCustomFileManager:(NGCustomFileManager *)_master
471 fileManager:(id<NGFileManager,NSObject>)_fm
473 self->master = _master;
474 self->fileManager = [_fm retain];
478 return [self initWithCustomFileManager:nil fileManager:nil];
482 [self->fileManager release];
486 - (void)resetMaster {
492 - (NGCustomFileManager *)master {
495 - (id<NGFileManager,NSObject>)fileManager {
496 return self->fileManager;
501 - (NSString *)rewriteAbsolutePath:(NSString *)_path {
507 - (BOOL)supportsGlobalIDs {
508 return [self->fileManager respondsToSelector:@selector(globalIDForPath:)];
511 @end /* NGCustomFileManagerInfo */