]> err.no Git - sope/blob - skyrix-sope/NGObjWeb/SoOFS/OFSFileRenderer.m
added svn:keywords and svn:ignore where appropriate. removed CVS artifacts.
[sope] / skyrix-sope / NGObjWeb / SoOFS / OFSFileRenderer.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
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 // $Id$
22
23 #include "OFSFileRenderer.h"
24 #include "OFSFile.h"
25 #include <NGObjWeb/WORequest.h>
26 #include <NGObjWeb/WOResponse.h>
27 #include <NGObjWeb/WOContext.h>
28 #include "NSException+HTTP.h"
29 #include "common.h"
30
31 @interface OFSFile(Render)
32
33 - (id)davContentLength;
34 - (NSDate *)davLastModified;
35
36 @end
37
38 @implementation OFSFileRenderer
39
40 static NSTimeZone *gmt = nil;
41
42 + (void)initialize {
43   gmt = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
44 }
45
46 + (id)sharedRenderer {
47   static OFSFileRenderer *singleton = nil;
48   if (singleton == nil)
49     singleton = [[OFSFileRenderer alloc] init];
50   return singleton;
51 }
52
53 /* rendering */
54
55 - (NSException *)renderHeadOfObject:(id)_object inContext:(WOContext *)_ctx {
56   WOResponse *r;
57   id tmp;
58   
59   r = [_ctx response];
60   
61   /* render headers */
62   
63   if ((tmp = [_object contentTypeInContext:_ctx]))
64     [r setHeader:tmp forKey:@"content-type"];
65   if ((tmp = [_object davContentLength]))
66     [r setHeader:tmp forKey:@"content-length"];
67   
68   if ((tmp = [_object davLastModified])) {
69     NSCalendarDate *date;
70
71 #if COCOA_Foundation_LIBRARY
72     date = [[NSCalendarDate alloc] initWithTimeIntervalSinceReferenceDate:
73                                      [tmp timeIntervalSinceReferenceDate]];
74 #else
75     date = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
76                                      [tmp timeIntervalSince1970]];
77 #endif
78     [date setTimeZone:gmt];
79     
80     // "Tue, 10 Jul 2001 14:09:06 GMT"
81     tmp = [date descriptionWithCalendarFormat:@"%a, %d %b %Y %H:%M:%S GMT"];
82     [date release];
83     [r setHeader:tmp forKey:@"last-modified"];
84   }
85   
86   return nil;
87 }
88
89 - (NSException *)renderBodyOfObject:(id)_object inContext:(WOContext *)_ctx {
90   WOResponse *r;
91   NSData     *content;
92   NSString   *storePath;
93   id fm;
94   
95   fm        = [_object fileManager];
96   storePath = [_object storagePath];
97   content   = [fm contentsAtPath:storePath];
98   
99   /* some error handling */
100   
101   if (content == nil) {
102     // TODO: should render exception ?
103     if ([fm respondsToSelector:@selector(lastException)])
104       return (id)[fm lastException];
105     return [NSException exceptionWithHTTPStatus:404 /* not found */];
106   }
107   
108   /* render body */
109   r = [_ctx response];
110   [r setContent:content];
111   return nil;
112 }
113
114 - (NSException *)renderObject:(id)_object inContext:(WOContext *)_ctx {
115   NSException *e;
116   
117   if ((e = [self renderHeadOfObject:_object inContext:_ctx]))
118     return e;
119   
120   if (![[[_ctx request] method] isEqualToString:@"HEAD"]) {
121     if ((e = [self renderBodyOfObject:_object inContext:_ctx]))
122       return e;
123   }
124   return nil;
125 }
126
127 - (BOOL)canRenderObject:(id)_object inContext:(WOContext *)_ctx {
128   return [_object isKindOfClass:[OFSFile class]];
129 }
130
131 @end /* OFSFileRenderer */