2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
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 "SoObject+SoDAV.h"
25 #include "NSException+HTTP.h"
26 #include "SoDAVLockManager.h"
27 #include <NGObjWeb/WOApplication.h>
30 /* informal interface for methods tried by the DAV key implementation */
32 @interface NSObject(SoResourceObject)
35 - (NSString *)displayName;
38 - (unsigned int)contentLength;
39 - (EOGlobalID *)globalID;
42 - (id)baseURLInContext:(id)_ctx;
46 @implementation NSObject(SoObjectSoDAVImp)
48 - (NSArray *)defaultWebDAVPropertyNamesInContext:(id)_ctx {
49 static NSArray *defNames = nil;
50 if (defNames == nil) {
51 defNames = [[[NSUserDefaults standardUserDefaults]
52 arrayForKey:@"SoDefaultWebDAVPropertyNames"]
55 #if 0 /* TODO: check whether this would be better ... */
56 keys = [[self soClassDescription] attributeKeys];
57 [self debugWithFormat:@"using keys from description: %@", keys];
64 - (BOOL)davIsCollection {
66 if ([self respondsToSelector:@selector(isCollection)])
67 return [self isCollection];
68 if ((v = [self valueForKey:@"NSFileType"])) {
69 if ([v isEqualToString:NSFileTypeDirectory])
74 return [[self toOneRelationshipKeys] count] > 0 ? YES : NO;
78 return [self davIsCollection];
81 - (BOOL)davHasSubFolders {
86 if (![self davIsCollection]) return NO;
87 ctx = [[WOApplication application] context];
89 e = [self davChildKeysInContext:ctx];
90 while ((childName = [e nextObject])) {
91 if ([[self lookupName:childName inContext:ctx acquire:NO] davIsFolder])
97 - (BOOL)davDenySubFolders {
98 return [self davIsCollection] ? NO : YES;
101 - (unsigned int)davChildCount {
105 if (![self davIsCollection]) return 0;
106 e = [self davChildKeysInContext:[[WOApplication application] context]];
107 for (i = 0; [e nextObject]; i++)
111 - (unsigned int)davObjectCount {
117 if (![self davIsCollection]) return 0;
119 ctx = [[WOApplication application] context];
121 e = [self davChildKeysInContext:ctx];
122 while ((childName = [e nextObject])) {
123 if (![[self lookupName:childName inContext:ctx acquire:NO] davIsCollection])
128 - (unsigned int)davVisibleCount {
129 return [self davObjectCount];
132 - (BOOL)davIsHidden {
137 if ([self respondsToSelector:@selector(globalID)])
138 return [self globalID];
139 return [self davURL];
142 return [self davUid];
145 - (BOOL)davIsStructuredDocument {
152 if ([self respondsToSelector:@selector(baseURLInContext:)]) {
153 url = [self baseURLInContext:[[WOApplication application] context]];
155 else if ([self respondsToSelector:@selector(baseURL)]) {
156 [self logWithFormat:@"object does not respond to baseURLInContext:?"];
157 url = [self baseURL];
161 @"WARNING: unable to calculate davURL for this object !"];
165 [self logWithFormat:@"WARNING: got no davURL for this object !"];
170 - (NSDate *)davLastModified {
172 if ((v = [self valueForKey:NSFileModificationDate])) return v;
173 return [NSDate date];
176 - (NSDate *)davCreationDate {
178 if ((v = [self valueForKey:@"NSFileCreationDate"])) return v;
179 if ((v = [self valueForKey:NSFileModificationDate])) return v;
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 */
189 return @"application/octet-stream";
192 - (id)davContentLength {
194 if ((v = [self valueForKey:NSFileSize])) return v;
195 if ([self respondsToSelector:@selector(contentLength)])
196 return [NSNumber numberWithUnsignedInt:[self contentLength]];
199 - (NSString *)davDisplayName {
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"])) ;
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];
217 if ([self respondsToSelector:@selector(path)])
218 return [[self path] lastPathComponent];
222 - (NSString *)davResourceType {
223 if ([self davIsCollection])
224 return @"collection";
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";
235 - (BOOL)davIsExecutable {
241 - (SoDAVLockManager *)davLockManagerInContext:(id)_ctx {
242 return [SoDAVLockManager sharedLockManager];
245 @end /* NSObject(SoObjectSoDAV) */
247 @implementation NSObject(SoObjectDAVMaps)
249 + (NSString *)lookupDefMapPlist {
251 #if !COMPILE_AS_FRAMEWORK
252 NSFileManager *fm = [NSFileManager defaultManager];
256 #if COMPILE_AS_FRAMEWORK
260 bundle = [NSBundle bundleForClass:self];
261 apath = [bundle pathForResource:@"DAVPropMap" ofType:@"plist"];
264 env = [[NSProcessInfo processInfo] environment];
265 relPath = @"Libraries";
266 relPath = [relPath stringByAppendingPathComponent:@"Resources"];
267 relPath = [relPath stringByAppendingPathComponent:@"NGObjWeb"];
268 relPath = [relPath stringByAppendingPathComponent:@"DAVPropMap.plist"];
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];
276 if (![fm fileExistsAtPath:apath]) {
277 apath = [env objectForKey:@"GNUSTEP_SYSTEM_ROOT"];
278 apath = [apath stringByAppendingPathComponent:relPath];
280 if (![fm fileExistsAtPath:apath]) {
283 if (![fm fileExistsAtPath:apath]) {
284 NSLog(@"ERROR: cannot find DAVPropMap.plist resource "
285 @"of NGObjWeb library !");
291 + (id)defaultWebDAVAttributeMap {
292 static NSDictionary *defMap = nil;
296 if ((path = [self lookupDefMapPlist]))
297 defMap = [[NSDictionary alloc] initWithContentsOfFile:path];
302 - (id)davAttributeMapInContext:(id)_ctx {
303 /* default is: do map some DAV properties, pass through anything else */
304 return [[self class] defaultWebDAVAttributeMap];
307 @end /* NSObject(SoObjectDAVMaps) */
309 #include <NGObjWeb/WOApplication.h>
310 #include <NGObjWeb/WORequestHandler.h>
312 @implementation WOCoreApplication(WebDAV)
314 - (BOOL)davIsCollection {
317 - (BOOL)davHasSubFolders {
321 return [self davURL];
324 return [self baseURL];
326 - (NSDate *)davLastModified {
327 return [NSDate date];
329 - (NSDate *)davCreationDate {
332 - (NSString *)davContentType {
335 - (id)davContentLength {
338 - (NSString *)davDisplayName {
342 @end /* WOCoreApplication(WebDAV) */
344 @implementation WOApplication(WebDAV)
346 - (NSString *)davDisplayName {
350 @end /* WOApplication(WebDAV) */
352 @implementation WORequestHandler(WebDAV)
354 - (BOOL)davIsCollection {
357 - (BOOL)davHasSubFolders {
362 return [self davURL];
365 - (NSDate *)davLastModified {
366 return [NSDate date];
368 - (NSDate *)davCreationDate {
372 - (NSString *)davContentType {
376 - (id)davContentLength {
380 @end /* WORequestHandler(WebDAV) */
382 #include "SoControlPanel.h"
384 @implementation SoControlPanel(WebDAV)
386 - (BOOL)davIsCollection {
389 - (BOOL)davHasSubFolders {
394 return [self davURL];
397 - (NSDate *)davLastModified {
398 return [NSDate date];
400 - (NSDate *)davCreationDate {
404 - (id)davContentLength {
408 @end /* SoControlPanel(WebDAV) */
410 @implementation NSObject(DavOperations)
412 - (NSException *)davSetProperties:(NSDictionary *)_setProps
413 removePropertiesNamed:(NSArray *)_delProps
416 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
417 reason:@"this object cannot edit object properties "
421 - (id)davCreateObject:(NSString *)_name
422 properties:(NSDictionary *)_props
425 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
426 reason:@"this object cannot create child objects "
430 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
431 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
432 reason:@"this object cannot create subcollections "
436 - (NSException *)davMoveToTargetObject:(id)_target newName:(NSString *)_name
439 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
440 reason:@"this object cannot be moved via WebDAV"];
443 - (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name
446 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
447 reason:@"this object cannot be copied via WebDAV"];
450 @end /* NSObject(DavOperations) */