]> err.no Git - sope/blob - sope-appserver/SoOFS/OFSFolder+SoDAV.m
ivar extensions to NGObjWeb core classes, moved SoOFS to separate project
[sope] / sope-appserver / SoOFS / OFSFolder+SoDAV.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: OFSFolder+SoDAV.m 4 2004-08-20 17:04:31Z helge $
22
23 #include "OFSFolder.h"
24 #include "common.h"
25
26 /*
27   Some special WebDAV keys:
28     .autodiskmounted - queried by the MacOSX DAV filesystem
29     .directory       - queried by Nautilus
30   
31   both seem to work if the keys do not exist (no special handling required).
32 */
33
34 @implementation OFSFolder(SoDAV)
35
36 static int davDebugOn = 0;
37
38 - (BOOL)davIsCollection {
39   return YES;
40 }
41 - (BOOL)davIsFolder {
42   /* this can be overridden by compound documents (aka filewrappers) */
43   return [self davIsCollection];
44 }
45
46 - (BOOL)davHasSubFolders {
47   /* search for subfolders (tries to be smart and load as little as p. ;-) */
48   NSArray  *ak;
49   unsigned i, count;
50   
51   if ((ak = [self allKeys]) == nil) return NO;
52   if ((count = [ak count]) == 0) return NO;
53   
54   /* first scan the already loaded children */
55   for (i = 0; i < count; i++) {
56     id child;
57     
58     child = [self->children objectForKey:[ak objectAtIndex:i]];
59     if ([child davIsFolder]) return YES;
60   }
61   
62   /* now scan all children */
63   
64   if (self->flags.didLoadAll) 
65     return NO; /* we've already seen all children */
66   [self allValues];          /* otherwise trigger a load */
67   
68   for (i = 0; i < count; i++) {
69     id child;
70     
71     child = [self->children objectForKey:[ak objectAtIndex:i]];
72     if ([child davIsFolder]) return YES;
73   }
74   
75   return NO;
76 }
77
78 - (NSString *)fileExtensionForChildrenInContext:(id)_ctx {
79   /* 
80      This can be used to enforce a common extension for all children, this is
81      useful for WebDAV directory listings (eg all children of an address folder
82      can appear as vcf files in cadaver or OSX).
83   */
84   return nil;
85 }
86
87 - (NSEnumerator *)davChildKeysInContext:(id)_ctx {
88   NSArray  *keys;
89   NSString *ext;
90   unsigned len;
91   
92   keys = [self allKeys];
93   if ((len = [keys count]) == 0) {
94     if (davDebugOn)
95       [self debugWithFormat:@"no DAV child keys for delivery ..."];
96     return [keys objectEnumerator];
97   }
98   
99   if ((ext = [self fileExtensionForChildrenInContext:_ctx])) {
100     NSMutableArray *ma;
101     unsigned i;
102     BOOL didChange;
103     
104     ma = [NSMutableArray arrayWithCapacity:len];
105     didChange = NO;
106     for (i = 0; i < len; i++) {
107       NSString *k, *pe;
108       
109       k = [keys objectAtIndex:i];
110       
111       if ((pe = [k pathExtension]) == nil)
112         [ma addObject:k];
113       else if ([pe length] == 0)
114         [ma addObject:k];
115       else {
116         k = [k stringByDeletingPathExtension];
117         k = [k stringByAppendingPathExtension:ext];
118         [ma addObject:k];
119         didChange = YES;
120       }
121     }
122     if (didChange) keys = ma;
123   }
124   if (davDebugOn) {
125     [self debugWithFormat:@"DAV child keys for delivery: %@",
126             [keys componentsJoinedByString:@","]];
127   }
128   return [keys objectEnumerator];
129 }
130
131 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
132   id<NSObject,NGFileManager> fm;
133   NSString *p;
134   BOOL     ok;
135   
136   if ([_name hasPrefix:@"."]) {
137     return [NSException exceptionWithHTTPStatus:405 /* not allowed */
138                         reason:@"creation of collections with a "
139                           @"leading dot is not allowed."];
140   }
141   
142   [self debugWithFormat:@"should create collection: %@", _name];
143   
144   p = [[self storagePath] stringByAppendingPathComponent:_name];
145   [self debugWithFormat:@"  path for new collection: %@", p];
146   
147   fm = [self fileManager];
148   ok = [fm createDirectoryAtPath:p attributes:nil];
149   if (!ok) {
150     [self debugWithFormat:@"  could not created collection at: %@", p];
151     return [NSException exceptionWithHTTPStatus:405 /* not allowed */
152                         reason:
153                           @"this OFSFolder could not create the collection"];
154   }
155   
156   [self debugWithFormat:@"  created collection."];
157   self->flags.didLoadAll = NO; /* not valid anymore */
158   return nil;
159 }
160
161 @end /* OFSFolder(SoDAV) */