]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WebDAV/SoObject+SoDAV.m
added FHS install hack to appserver
[sope] / sope-appserver / NGObjWeb / WebDAV / SoObject+SoDAV.m
1 /*
2   Copyright (C) 2002-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
22 #include "SoObject+SoDAV.h"
23 #include "SoObject.h"
24 #include "NSException+HTTP.h"
25 #include "SoDAVLockManager.h"
26 #include <NGObjWeb/WOApplication.h>
27 #include "common.h"
28
29 /* informal interface for methods tried by the DAV key implementation */
30
31 @interface NSObject(SoResourceObject)
32
33 - (BOOL)isCollection;
34 - (NSString *)displayName;
35 - (NSString *)path;
36
37 - (unsigned int)contentLength;
38 - (EOGlobalID *)globalID;
39
40 - (id)baseURL;
41 - (id)baseURLInContext:(id)_ctx;
42
43 @end
44
45 @implementation NSObject(SoObjectSoDAVImp)
46
47 - (NSArray *)defaultWebDAVPropertyNamesInContext:(id)_ctx {
48   static NSArray *defNames = nil;
49   if (defNames == nil) {
50     defNames = [[[NSUserDefaults standardUserDefaults] 
51                                  arrayForKey:@"SoDefaultWebDAVPropertyNames"]
52                                  copy];
53   }
54 #if 0 /* TODO: check whether this would be better ... */
55   keys = [[self soClassDescription] attributeKeys];
56   [self debugWithFormat:@"using keys from description: %@", keys];
57 #endif
58   return defNames;
59 }
60
61 /* attributes */
62
63 - (BOOL)davIsCollection {
64   id v;
65   if ([self respondsToSelector:@selector(isCollection)])
66     return [self isCollection];
67   if ((v = [self valueForKey:@"NSFileType"])) {
68     if ([v isEqualToString:NSFileTypeDirectory])
69       return YES;
70     else
71       return NO;
72   }
73   return [[self toOneRelationshipKeys] count] > 0 ? YES : NO;
74 }
75
76 - (BOOL)davIsFolder {
77   return [self davIsCollection];
78 }
79
80 - (BOOL)davHasSubFolders {
81   NSEnumerator *e;
82   NSString *childName;
83   id       ctx;
84   
85   if (![self davIsCollection]) return NO;
86   ctx = [[WOApplication application] context];
87   
88   e = [self davChildKeysInContext:ctx];
89   while ((childName = [e nextObject])) {
90     if ([[self lookupName:childName inContext:ctx acquire:NO] davIsFolder])
91       return YES;
92   }
93   return NO;
94 }
95
96 - (BOOL)davDenySubFolders {
97   return [self davIsCollection] ? NO : YES;
98 }
99
100 - (unsigned int)davChildCount {
101   NSEnumerator *e;
102   unsigned int i;
103   
104   if (![self davIsCollection]) return 0;
105   e = [self davChildKeysInContext:[[WOApplication application] context]];
106   for (i = 0; [e nextObject]; i++)
107     ;
108   return i;
109 }
110 - (unsigned int)davObjectCount {
111   NSEnumerator *e;
112   unsigned int i;
113   NSString     *childName;
114   WOContext    *ctx;
115   
116   if (![self davIsCollection]) return 0;
117   
118   ctx = [[WOApplication application] context];
119   i = 0;
120   e = [self davChildKeysInContext:ctx];
121   while ((childName = [e nextObject])) {
122     if (![[self lookupName:childName inContext:ctx acquire:NO] davIsCollection])
123       i++;
124   }
125   return i;
126 }
127 - (unsigned int)davVisibleCount {
128   return [self davObjectCount];
129 }
130
131 - (BOOL)davIsHidden {
132   return NO;
133 }
134
135 - (id)davUid {
136   if ([self respondsToSelector:@selector(globalID)])
137     return [self globalID];
138   return [self davURL];
139 }
140 - (id)davEntityTag {
141   return [self davUid];
142 }
143
144 - (BOOL)davIsStructuredDocument {
145   return NO;
146 }
147
148 - (id)davURL {
149   id url;
150   
151   if ([self respondsToSelector:@selector(baseURLInContext:)]) {
152     url = [self baseURLInContext:[[WOApplication application] context]];
153   }
154   else if ([self respondsToSelector:@selector(baseURL)]) {
155     [self logWithFormat:@"object does not respond to baseURLInContext:?"];
156     url = [self baseURL];
157   }
158   else {
159     [self logWithFormat:
160             @"WARNING: unable to calculate davURL for this object !"];
161     url = nil;
162   }
163   if (url == nil)
164     [self logWithFormat:@"WARNING: got no davURL for this object !"];
165   
166   return url;
167 }
168
169 - (NSDate *)davLastModified {
170   id v;
171   if ((v = [self valueForKey:NSFileModificationDate])) return v;
172   return [NSDate date];
173 }
174
175 - (NSDate *)davCreationDate {
176   id v;
177   if ((v = [self valueForKey:@"NSFileCreationDate"]))  return v;
178   if ((v = [self valueForKey:NSFileModificationDate])) return v;
179   return nil;
180 }
181
182 - (NSString *)davContentType {
183   if ([self davIsFolder]) {
184     //return @"x-directory/webdav"; /* this is taken from Nautilus */
185     return @"httpd/unix-directory"; /* this is returned by Apache */
186   }
187   
188   return @"application/octet-stream";
189 }
190
191 - (id)davContentLength {
192   id v;
193   if ((v = [self valueForKey:NSFileSize])) return v;
194   if ([self respondsToSelector:@selector(contentLength)])
195     return [NSNumber numberWithUnsignedInt:[self contentLength]];
196   return 0;
197 }
198 - (NSString *)davDisplayName {
199   id v = nil;
200   
201   if ([self respondsToSelector:@selector(displayName)])
202     return [self displayName];
203 #if COCOA_Foundation_LIBRARY
204   NS_DURING /* handle query for unbound key is easily triggered ... */
205     if ((v = [self valueForKey:@"NSFileSubject"])) ;
206     else if ((v = [self valueForKey:@"NSFileName"])) ;
207     else if ((v = [self valueForKey:@"NSFilePath"])) ;
208   NS_HANDLER
209     v = nil;
210   NS_ENDHANDLER;
211 #else
212   if ((v = [self valueForKey:@"NSFileSubject"])) return v;
213   if ((v = [self valueForKey:@"NSFileName"])) return v;
214   if ((v = [self valueForKey:@"NSFilePath"])) return [v lastPathComponent];
215 #endif
216   if ([self respondsToSelector:@selector(path)])
217     return [[self path] lastPathComponent];
218   return nil;
219 }
220
221 - (NSString *)davResourceType {
222   if ([self davIsCollection])
223     return @"collection";
224   return nil;
225 }
226
227 - (NSString *)davContentClass {
228   /* this doesn't return something really useful, override if necessary ! */
229   return ([self davIsFolder])
230     ? @"urn:content-classes:folder"
231     : @"urn:content-classes:item";
232 }
233
234 - (BOOL)davIsExecutable {
235   return NO;
236 }
237
238 /* lock manager */
239
240 - (SoDAVLockManager *)davLockManagerInContext:(id)_ctx {
241   return [SoDAVLockManager sharedLockManager];
242 }
243
244 @end /* NSObject(SoObjectSoDAV) */
245
246 @interface WOCoreApplication(Resources)
247 + (NSString *)findNGObjWebResource:(NSString *)_name ofType:(NSString *)_ext;
248 @end
249
250 @implementation NSObject(SoObjectDAVMaps)
251
252 + (id)defaultWebDAVAttributeMap {
253   static NSDictionary *defMap = nil;
254   if (defMap == nil) {
255     NSString *path;
256     
257     path = [WOApplication findNGObjWebResource:@"DAVPropMap" ofType:@"plist"];
258     if (path != nil)
259       defMap = [[NSDictionary alloc] initWithContentsOfFile:path];
260   }
261   return defMap;
262 }
263
264 - (id)davAttributeMapInContext:(id)_ctx {
265   /* default is: do map some DAV properties, pass through anything else */
266   return [[self class] defaultWebDAVAttributeMap];
267 }
268
269 @end /* NSObject(SoObjectDAVMaps) */
270
271 #include <NGObjWeb/WOApplication.h>
272 #include <NGObjWeb/WORequestHandler.h>
273
274 @implementation WOCoreApplication(WebDAV)
275
276 - (BOOL)davIsCollection {
277   return YES;
278 }
279 - (BOOL)davHasSubFolders {
280   return YES;
281 }
282 - (id)davUid {
283   return [self davURL];
284 }
285 - (id)davURL {
286   return [self baseURL];
287 }
288 - (NSDate *)davLastModified {
289   return [NSDate date];
290 }
291 - (NSDate *)davCreationDate {
292   return nil;
293 }
294 - (NSString *)davContentType {
295   return @"text/html";
296 }
297 - (id)davContentLength {
298   return 0;
299 }
300 - (NSString *)davDisplayName {
301   return @"ROOT";
302 }
303
304 @end /* WOCoreApplication(WebDAV) */
305
306 @implementation WOApplication(WebDAV)
307
308 - (NSString *)davDisplayName {
309   return [self name];
310 }
311
312 @end /* WOApplication(WebDAV) */
313
314 @implementation WORequestHandler(WebDAV)
315
316 - (BOOL)davIsCollection {
317   return YES;
318 }
319 - (BOOL)davHasSubFolders {
320   return YES;
321 }
322
323 - (id)davUid {
324   return [self davURL];
325 }
326
327 - (NSDate *)davLastModified {
328   return [NSDate date];
329 }
330 - (NSDate *)davCreationDate {
331   return nil;
332 }
333
334 - (NSString *)davContentType {
335   return @"text/html";
336 }
337
338 - (id)davContentLength {
339   return 0;
340 }
341
342 @end /* WORequestHandler(WebDAV) */
343
344 #include "SoControlPanel.h"
345
346 @implementation SoControlPanel(WebDAV)
347
348 - (BOOL)davIsCollection {
349   return YES;
350 }
351 - (BOOL)davHasSubFolders {
352   return YES;
353 }
354
355 - (id)davUid {
356   return [self davURL];
357 }
358
359 - (NSDate *)davLastModified {
360   return [NSDate date];
361 }
362 - (NSDate *)davCreationDate {
363   return nil;
364 }
365
366 - (id)davContentLength {
367   return 0;
368 }
369
370 @end /* SoControlPanel(WebDAV) */
371
372 @implementation NSObject(DavOperations)
373
374 - (NSException *)davSetProperties:(NSDictionary *)_setProps
375   removePropertiesNamed:(NSArray *)_delProps
376   inContext:(id)_ctx
377 {
378   return [NSException exceptionWithHTTPStatus:405 /* not allowed */
379                       reason:@"this object cannot edit object properties "
380                       @"via WebDAV"];
381 }
382
383 - (id)davCreateObject:(NSString *)_name
384   properties:(NSDictionary *)_props
385   inContext:(id)_ctx
386 {
387   return [NSException exceptionWithHTTPStatus:405 /* not allowed */
388                       reason:@"this object cannot create child objects "
389                       @"via WebDAV"];
390 }
391
392 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
393   return [NSException exceptionWithHTTPStatus:405 /* not allowed */
394                       reason:@"this object cannot create subcollections "
395                       @"via WebDAV"];
396 }
397
398 - (NSException *)davMoveToTargetObject:(id)_target newName:(NSString *)_name
399   inContext:(id)_ctx
400 {
401   return [NSException exceptionWithHTTPStatus:405 /* not allowed */
402                       reason:@"this object cannot be moved via WebDAV"];
403 }
404
405 - (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name
406   inContext:(id)_ctx
407 {
408   return [NSException exceptionWithHTTPStatus:405 /* not allowed */
409                       reason:@"this object cannot be copied via WebDAV"];
410 }
411
412 @end /* NSObject(DavOperations) */