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