2 Copyright (C) 2002-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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
22 #include "SoObject+SoDAV.h"
24 #include "NSException+HTTP.h"
25 #include "SoDAVLockManager.h"
26 #include <NGObjWeb/WOApplication.h>
29 /* informal interface for methods tried by the DAV key implementation */
31 @interface NSObject(SoResourceObject)
34 - (NSString *)displayName;
37 - (unsigned int)contentLength;
38 - (EOGlobalID *)globalID;
41 - (id)baseURLInContext:(id)_ctx;
45 @implementation NSObject(SoObjectSoDAVImp)
47 - (NSArray *)defaultWebDAVPropertyNamesInContext:(id)_ctx {
48 static NSArray *defNames = nil;
49 if (defNames == nil) {
50 defNames = [[[NSUserDefaults standardUserDefaults]
51 arrayForKey:@"SoDefaultWebDAVPropertyNames"]
54 #if 0 /* TODO: check whether this would be better ... */
55 keys = [[self soClassDescription] attributeKeys];
56 [self debugWithFormat:@"using keys from description: %@", keys];
63 - (BOOL)davIsCollection {
66 if ([self respondsToSelector:@selector(isCollection)])
67 return [self isCollection];
68 if ([(v = [self valueForKey:@"NSFileType"]) isNotNull]) {
69 if ([v isEqualToString:NSFileTypeDirectory])
74 if ([[self toManyRelationshipKeys] count] > 0)
76 if ([[self toOneRelationshipKeys] count] > 0)
82 return [self davIsCollection];
85 - (BOOL)davHasSubFolders {
90 if (![self davIsCollection]) return NO;
91 ctx = [[WOApplication application] context];
93 e = [self davChildKeysInContext:ctx];
94 while ((childName = [e nextObject])) {
95 if ([[self lookupName:childName inContext:ctx acquire:NO] davIsFolder])
101 - (BOOL)davDenySubFolders {
102 return [self davIsCollection] ? NO : YES;
105 - (unsigned int)davChildCount {
109 if (![self davIsCollection]) return 0;
110 e = [self davChildKeysInContext:[[WOApplication application] context]];
111 for (i = 0; [e nextObject]; i++)
115 - (unsigned int)davObjectCount {
121 if (![self davIsCollection]) return 0;
123 ctx = [[WOApplication application] context];
125 e = [self davChildKeysInContext:ctx];
126 while ((childName = [e nextObject])) {
127 if (![[self lookupName:childName inContext:ctx acquire:NO] davIsCollection])
132 - (unsigned int)davVisibleCount {
133 return [self davObjectCount];
136 - (BOOL)davIsHidden {
141 if ([self respondsToSelector:@selector(globalID)])
142 return [self globalID];
143 return [self davURL];
146 return [self davUid];
149 - (BOOL)davIsStructuredDocument {
156 if ([self respondsToSelector:@selector(baseURLInContext:)]) {
157 url = [self baseURLInContext:[[WOApplication application] context]];
159 else if ([self respondsToSelector:@selector(baseURL)]) {
160 [self logWithFormat:@"object does not respond to baseURLInContext:?"];
161 url = [self baseURL];
165 @"WARNING: unable to calculate davURL for this object !"];
169 [self logWithFormat:@"WARNING: got no davURL for this object !"];
174 - (NSDate *)davLastModified {
176 if ((v = [self valueForKey:NSFileModificationDate])) return v;
177 return [NSDate date];
180 - (NSDate *)davCreationDate {
182 if ((v = [self valueForKey:@"NSFileCreationDate"])) return v;
183 if ((v = [self valueForKey:NSFileModificationDate])) return v;
187 - (NSString *)davContentType {
188 if ([self davIsFolder]) {
189 //return @"x-directory/webdav"; /* this is taken from Nautilus */
190 return @"httpd/unix-directory"; /* this is returned by Apache */
193 return @"application/octet-stream";
196 - (id)davContentLength {
198 if ((v = [self valueForKey:NSFileSize])) return v;
199 if ([self respondsToSelector:@selector(contentLength)])
200 return [NSNumber numberWithUnsignedInt:[self contentLength]];
203 - (NSString *)davDisplayName {
206 if ([self respondsToSelector:@selector(displayName)])
207 return [self displayName];
208 #if COCOA_Foundation_LIBRARY
209 NS_DURING /* handle query for unbound key is easily triggered ... */
210 if ((v = [self valueForKey:@"NSFileSubject"])) ;
211 else if ((v = [self valueForKey:@"NSFileName"])) ;
212 else if ((v = [self valueForKey:@"NSFilePath"])) ;
217 if ((v = [self valueForKey:@"NSFileSubject"])) return v;
218 if ((v = [self valueForKey:@"NSFileName"])) return v;
219 if ((v = [self valueForKey:@"NSFilePath"])) return [v lastPathComponent];
221 if ([self respondsToSelector:@selector(path)])
222 return [[self path] lastPathComponent];
226 - (NSString *)davResourceType {
227 if ([self davIsCollection])
228 return @"collection";
232 - (NSString *)davContentClass {
233 /* this doesn't return something really useful, override if necessary ! */
234 return ([self davIsFolder])
235 ? @"urn:content-classes:folder"
236 : @"urn:content-classes:item";
239 - (BOOL)davIsExecutable {
245 - (SoDAVLockManager *)davLockManagerInContext:(id)_ctx {
246 return [SoDAVLockManager sharedLockManager];
249 @end /* NSObject(SoObjectSoDAV) */
251 @interface WOCoreApplication(Resources)
252 + (NSString *)findNGObjWebResource:(NSString *)_name ofType:(NSString *)_ext;
255 @implementation NSObject(SoObjectDAVMaps)
257 + (id)defaultWebDAVAttributeMap {
258 static NSDictionary *defMap = nil;
262 path = [WOApplication findNGObjWebResource:@"DAVPropMap" ofType:@"plist"];
264 defMap = [[NSDictionary alloc] initWithContentsOfFile:path];
269 - (id)davAttributeMapInContext:(id)_ctx {
270 /* default is: do map some DAV properties, pass through anything else */
271 return [[self class] defaultWebDAVAttributeMap];
274 @end /* NSObject(SoObjectDAVMaps) */
276 #include <NGObjWeb/WOApplication.h>
277 #include <NGObjWeb/WORequestHandler.h>
279 @implementation WOCoreApplication(WebDAV)
281 - (BOOL)davIsCollection {
284 - (BOOL)davHasSubFolders {
288 return [self davURL];
291 return [self baseURL];
293 - (NSDate *)davLastModified {
294 return [NSDate date];
296 - (NSDate *)davCreationDate {
299 - (NSString *)davContentType {
302 - (id)davContentLength {
305 - (NSString *)davDisplayName {
309 @end /* WOCoreApplication(WebDAV) */
311 @implementation WOApplication(WebDAV)
313 - (NSString *)davDisplayName {
317 @end /* WOApplication(WebDAV) */
319 @implementation WORequestHandler(WebDAV)
321 - (BOOL)davIsCollection {
324 - (BOOL)davHasSubFolders {
329 return [self davURL];
332 - (NSDate *)davLastModified {
333 return [NSDate date];
335 - (NSDate *)davCreationDate {
339 - (NSString *)davContentType {
343 - (id)davContentLength {
347 @end /* WORequestHandler(WebDAV) */
349 #include "SoControlPanel.h"
351 @implementation SoControlPanel(WebDAV)
353 - (BOOL)davIsCollection {
356 - (BOOL)davHasSubFolders {
361 return [self davURL];
364 - (NSDate *)davLastModified {
365 return [NSDate date];
367 - (NSDate *)davCreationDate {
371 - (id)davContentLength {
375 @end /* SoControlPanel(WebDAV) */
377 @implementation NSObject(DavOperations)
379 - (NSException *)davSetProperties:(NSDictionary *)_setProps
380 removePropertiesNamed:(NSArray *)_delProps
383 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
384 reason:@"this object cannot edit object properties "
388 - (id)davCreateObject:(NSString *)_name
389 properties:(NSDictionary *)_props
392 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
393 reason:@"this object cannot create child objects "
397 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
398 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
399 reason:@"this object cannot create subcollections "
403 - (NSException *)davMoveToTargetObject:(id)_target newName:(NSString *)_name
406 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
407 reason:@"this object cannot be moved via WebDAV"];
410 - (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name
413 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
414 reason:@"this object cannot be copied via WebDAV"];
417 @end /* NSObject(DavOperations) */