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