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