2 Copyright (C) 2002-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
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];
164 [self warnWithFormat:@"unable to calculate davURL for this object !"];
168 [self warnWithFormat:@"got no davURL for this object !"];
173 - (NSDate *)davLastModified {
175 if ((v = [self valueForKey:NSFileModificationDate])) return v;
176 return [NSDate date];
179 - (NSDate *)davCreationDate {
181 if ((v = [self valueForKey:@"NSFileCreationDate"])) return v;
182 if ((v = [self valueForKey:NSFileModificationDate])) return v;
186 - (NSString *)davContentType {
187 if ([self davIsFolder]) {
188 //return @"x-directory/webdav"; /* this is taken from Nautilus */
189 return @"httpd/unix-directory"; /* this is returned by Apache */
192 return @"application/octet-stream";
195 - (id)davContentLength {
197 if ((v = [self valueForKey:NSFileSize])) return v;
198 if ([self respondsToSelector:@selector(contentLength)])
199 return [NSNumber numberWithUnsignedInt:[self contentLength]];
202 - (NSString *)davDisplayName {
205 if ([self respondsToSelector:@selector(displayName)])
206 return [self displayName];
207 #if COCOA_Foundation_LIBRARY
208 NS_DURING /* handle query for unbound key is easily triggered ... */
209 if ((v = [self valueForKey:@"NSFileSubject"])) ;
210 else if ((v = [self valueForKey:@"NSFileName"])) ;
211 else if ((v = [self valueForKey:@"NSFilePath"])) ;
216 if ((v = [self valueForKey:@"NSFileSubject"])) return v;
217 if ((v = [self valueForKey:@"NSFileName"])) return v;
218 if ((v = [self valueForKey:@"NSFilePath"])) return [v lastPathComponent];
220 if ([self respondsToSelector:@selector(path)])
221 return [[self path] lastPathComponent];
225 - (NSString *)davResourceType {
226 if ([self davIsCollection])
227 return @"collection";
231 - (NSString *)davContentClass {
232 /* this doesn't return something really useful, override if necessary ! */
233 return ([self davIsFolder])
234 ? @"urn:content-classes:folder"
235 : @"urn:content-classes:item";
238 - (BOOL)davIsExecutable {
244 - (SoDAVLockManager *)davLockManagerInContext:(id)_ctx {
245 return [SoDAVLockManager sharedLockManager];
248 @end /* NSObject(SoObjectSoDAV) */
250 @interface WOCoreApplication(Resources)
251 + (NSString *)findNGObjWebResource:(NSString *)_name ofType:(NSString *)_ext;
254 @implementation NSObject(SoObjectDAVMaps)
256 + (id)defaultWebDAVAttributeMap {
257 static NSDictionary *defMap = nil;
261 path = [WOApplication findNGObjWebResource:@"DAVPropMap" ofType:@"plist"];
263 defMap = [[NSDictionary alloc] initWithContentsOfFile:path];
268 - (id)davAttributeMapInContext:(id)_ctx {
269 /* default is: do map some DAV properties, pass through anything else */
270 return [[self class] defaultWebDAVAttributeMap];
273 @end /* NSObject(SoObjectDAVMaps) */
275 #include <NGObjWeb/WOApplication.h>
276 #include <NGObjWeb/WORequestHandler.h>
278 @implementation WOCoreApplication(WebDAV)
280 - (BOOL)davIsCollection {
283 - (BOOL)davHasSubFolders {
287 return [self davURL];
290 return [self baseURL];
292 - (NSDate *)davLastModified {
293 return [NSDate date];
295 - (NSDate *)davCreationDate {
298 - (NSString *)davContentType {
301 - (id)davContentLength {
304 - (NSString *)davDisplayName {
308 @end /* WOCoreApplication(WebDAV) */
310 @implementation WOApplication(WebDAV)
312 - (NSString *)davDisplayName {
316 @end /* WOApplication(WebDAV) */
318 @implementation WORequestHandler(WebDAV)
320 - (BOOL)davIsCollection {
323 - (BOOL)davHasSubFolders {
328 return [self davURL];
331 - (NSDate *)davLastModified {
332 return [NSDate date];
334 - (NSDate *)davCreationDate {
338 - (NSString *)davContentType {
342 - (id)davContentLength {
346 @end /* WORequestHandler(WebDAV) */
348 #include "SoControlPanel.h"
350 @implementation SoControlPanel(WebDAV)
352 - (BOOL)davIsCollection {
355 - (BOOL)davHasSubFolders {
360 return [self davURL];
363 - (NSDate *)davLastModified {
364 return [NSDate date];
366 - (NSDate *)davCreationDate {
370 - (id)davContentLength {
374 @end /* SoControlPanel(WebDAV) */
376 @implementation NSObject(DavOperations)
378 - (NSException *)davSetProperties:(NSDictionary *)_setProps
379 removePropertiesNamed:(NSArray *)_delProps
382 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
383 reason:@"this object cannot edit object properties "
387 - (id)davCreateObject:(NSString *)_name
388 properties:(NSDictionary *)_props
391 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
392 reason:@"this object cannot create child objects "
396 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
397 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
398 reason:@"this object cannot create subcollections "
402 - (NSException *)davMoveToTargetObject:(id)_target newName:(NSString *)_name
405 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
406 reason:@"this object cannot be moved via WebDAV"];
409 - (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name
412 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
413 reason:@"this object cannot be copied via WebDAV"];
416 @end /* NSObject(DavOperations) */