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 {
65 if ([self respondsToSelector:@selector(isCollection)])
66 return [self isCollection];
67 if ((v = [self valueForKey:@"NSFileType"])) {
68 if ([v isEqualToString:NSFileTypeDirectory])
73 return [[self toOneRelationshipKeys] count] > 0 ? YES : NO;
77 return [self davIsCollection];
80 - (BOOL)davHasSubFolders {
85 if (![self davIsCollection]) return NO;
86 ctx = [[WOApplication application] context];
88 e = [self davChildKeysInContext:ctx];
89 while ((childName = [e nextObject])) {
90 if ([[self lookupName:childName inContext:ctx acquire:NO] davIsFolder])
96 - (BOOL)davDenySubFolders {
97 return [self davIsCollection] ? NO : YES;
100 - (unsigned int)davChildCount {
104 if (![self davIsCollection]) return 0;
105 e = [self davChildKeysInContext:[[WOApplication application] context]];
106 for (i = 0; [e nextObject]; i++)
110 - (unsigned int)davObjectCount {
116 if (![self davIsCollection]) return 0;
118 ctx = [[WOApplication application] context];
120 e = [self davChildKeysInContext:ctx];
121 while ((childName = [e nextObject])) {
122 if (![[self lookupName:childName inContext:ctx acquire:NO] davIsCollection])
127 - (unsigned int)davVisibleCount {
128 return [self davObjectCount];
131 - (BOOL)davIsHidden {
136 if ([self respondsToSelector:@selector(globalID)])
137 return [self globalID];
138 return [self davURL];
141 return [self davUid];
144 - (BOOL)davIsStructuredDocument {
151 if ([self respondsToSelector:@selector(baseURLInContext:)]) {
152 url = [self baseURLInContext:[[WOApplication application] context]];
154 else if ([self respondsToSelector:@selector(baseURL)]) {
155 [self logWithFormat:@"object does not respond to baseURLInContext:?"];
156 url = [self baseURL];
160 @"WARNING: unable to calculate davURL for this object !"];
164 [self logWithFormat:@"WARNING: got no davURL for this object !"];
169 - (NSDate *)davLastModified {
171 if ((v = [self valueForKey:NSFileModificationDate])) return v;
172 return [NSDate date];
175 - (NSDate *)davCreationDate {
177 if ((v = [self valueForKey:@"NSFileCreationDate"])) return v;
178 if ((v = [self valueForKey:NSFileModificationDate])) return v;
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 */
188 return @"application/octet-stream";
191 - (id)davContentLength {
193 if ((v = [self valueForKey:NSFileSize])) return v;
194 if ([self respondsToSelector:@selector(contentLength)])
195 return [NSNumber numberWithUnsignedInt:[self contentLength]];
198 - (NSString *)davDisplayName {
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"])) ;
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];
216 if ([self respondsToSelector:@selector(path)])
217 return [[self path] lastPathComponent];
221 - (NSString *)davResourceType {
222 if ([self davIsCollection])
223 return @"collection";
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";
234 - (BOOL)davIsExecutable {
240 - (SoDAVLockManager *)davLockManagerInContext:(id)_ctx {
241 return [SoDAVLockManager sharedLockManager];
244 @end /* NSObject(SoObjectSoDAV) */
246 @interface WOCoreApplication(Resources)
247 + (NSString *)findNGObjWebResource:(NSString *)_name ofType:(NSString *)_ext;
250 @implementation NSObject(SoObjectDAVMaps)
252 + (id)defaultWebDAVAttributeMap {
253 static NSDictionary *defMap = nil;
257 path = [WOApplication findNGObjWebResource:@"DAVPropMap" ofType:@"plist"];
259 defMap = [[NSDictionary alloc] initWithContentsOfFile:path];
264 - (id)davAttributeMapInContext:(id)_ctx {
265 /* default is: do map some DAV properties, pass through anything else */
266 return [[self class] defaultWebDAVAttributeMap];
269 @end /* NSObject(SoObjectDAVMaps) */
271 #include <NGObjWeb/WOApplication.h>
272 #include <NGObjWeb/WORequestHandler.h>
274 @implementation WOCoreApplication(WebDAV)
276 - (BOOL)davIsCollection {
279 - (BOOL)davHasSubFolders {
283 return [self davURL];
286 return [self baseURL];
288 - (NSDate *)davLastModified {
289 return [NSDate date];
291 - (NSDate *)davCreationDate {
294 - (NSString *)davContentType {
297 - (id)davContentLength {
300 - (NSString *)davDisplayName {
304 @end /* WOCoreApplication(WebDAV) */
306 @implementation WOApplication(WebDAV)
308 - (NSString *)davDisplayName {
312 @end /* WOApplication(WebDAV) */
314 @implementation WORequestHandler(WebDAV)
316 - (BOOL)davIsCollection {
319 - (BOOL)davHasSubFolders {
324 return [self davURL];
327 - (NSDate *)davLastModified {
328 return [NSDate date];
330 - (NSDate *)davCreationDate {
334 - (NSString *)davContentType {
338 - (id)davContentLength {
342 @end /* WORequestHandler(WebDAV) */
344 #include "SoControlPanel.h"
346 @implementation SoControlPanel(WebDAV)
348 - (BOOL)davIsCollection {
351 - (BOOL)davHasSubFolders {
356 return [self davURL];
359 - (NSDate *)davLastModified {
360 return [NSDate date];
362 - (NSDate *)davCreationDate {
366 - (id)davContentLength {
370 @end /* SoControlPanel(WebDAV) */
372 @implementation NSObject(DavOperations)
374 - (NSException *)davSetProperties:(NSDictionary *)_setProps
375 removePropertiesNamed:(NSArray *)_delProps
378 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
379 reason:@"this object cannot edit object properties "
383 - (id)davCreateObject:(NSString *)_name
384 properties:(NSDictionary *)_props
387 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
388 reason:@"this object cannot create child objects "
392 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
393 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
394 reason:@"this object cannot create subcollections "
398 - (NSException *)davMoveToTargetObject:(id)_target newName:(NSString *)_name
401 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
402 reason:@"this object cannot be moved via WebDAV"];
405 - (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name
408 return [NSException exceptionWithHTTPStatus:405 /* not allowed */
409 reason:@"this object cannot be copied via WebDAV"];
412 @end /* NSObject(DavOperations) */