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
23 #include "OFSFolder.h"
24 #include "OFSFactoryContext.h"
25 #include "OFSFileRenderer.h"
26 #include <NGObjWeb/WOResponse.h>
29 @implementation OFSFile
32 return [super version] + 0 /* v1 */;
35 static BOOL didInit = NO;
38 NSAssert2([super version] == 1,
39 @"invalid superclass (%@) version %i !",
40 NSStringFromClass([self superclass]), [super version]);
45 [self->attrCache release];
51 - (BOOL)isCollection {
58 - (NSStringEncoding)contentEncoding {
59 return [NSString defaultCStringEncoding];
62 - (NSString *)contentAsString {
66 if ((data = [[self fileManager] contentsAtPath:[self storagePath]]) == nil)
69 s = [[NSString alloc] initWithData:data encoding:[self contentEncoding]];
70 return [s autorelease];
75 - (NSException *)writeState:(id)_value {
76 // TODO: better name: -writeContent:?
81 return [NSException exceptionWithHTTPStatus:500
82 reason:@"missing value to write !"];
85 // TODO: could support some more objects ?
86 if ([_value isKindOfClass:[NSData class]])
89 data = [[_value stringValue] dataUsingEncoding:[self contentEncoding]];
91 fm = [self fileManager];
92 if (![fm writeContents:data atPath:[self storagePath]]) {
93 if ([fm respondsToSelector:@selector(lastException)]) {
94 NSException *e = [fm lastException];
95 [self logWithFormat:@"write of %i bytes failed: %@", [data length], e];
99 return [NSException exceptionWithHTTPStatus:500
100 reason:@"could not write content, reason unknown"];
103 return nil; /* nil is OK */
108 - (NSDictionary *)fileAttributes {
111 if ((fm = [self fileManager]) == nil)
113 if (self->attrCache == nil) {
115 [[fm fileAttributesAtPath:[self storagePath] traverseLink:NO] copy];
117 return self->attrCache;
122 - (BOOL)allowAccessToFileAttribute:(NSString *)_name {
126 - (id)valueForKey:(NSString *)_name {
130 if ((nl = [_name length]) == 0)
133 c = [_name characterAtIndex:0];
134 if (c == 'N' && (nl > 6)) {
135 if ([_name hasPrefix:@"NSFile"]) {
136 if ([self allowAccessToFileAttribute:_name])
137 return [[self fileAttributes] objectForKey:_name];
141 return [super valueForKey:_name];
146 - (NSString *)contentTypeInContext:(WOContext *)_ctx {
147 NSString *ext, *type;
150 if ((ext = [[self nameInContainer] pathExtension])) {
151 // TODO: read /etc/mime.types
152 if ([ext isEqualToString:@"html"]) type = @"text/html";
153 else if ([ext isEqualToString:@"xhtml"]) type = @"text/xhtml";
154 else if ([ext isEqualToString:@"gif"]) type = @"image/gif";
155 else if ([ext isEqualToString:@"png"]) type = @"image/png";
157 return type ? type : @"application/octet-stream";
160 - (id)davContentLength {
161 return [[self fileAttributes] objectForKey:NSFileSize];
163 - (NSDate *)davLastModified {
164 return [[self fileAttributes] objectForKey:NSFileModificationDate];
167 - (id)rendererForObject:(id)_object inContext:(WOContext *)_ctx {
171 - (id)viewAction:(WOContext *)_ctx {
174 - (id)GETAction:(WOContext *)_ctx {
177 - (id)HEADAction:(WOContext *)_ctx {
181 - (id)PUTAction:(WOContext *)_ctx {
185 if ((e = [self validateForSave])) {
186 [self debugWithFormat:@"object did not validate for save ..."];
190 if ((content = [[_ctx request] content]) == nil)
191 content = [NSData data];
193 if ((e = [self writeState:content]))
199 /* version control */
201 - (BOOL)isCvsControlled {
202 return [[self container] isCvsControlled];
204 - (BOOL)isSvnControlled {
205 return [[self container] isSvnControlled];
210 + (id)instantiateInFactoryContext:(OFSFactoryContext *)_ctx {
213 object = [[self soClass] instantiateObject];
214 [object takeStorageInfoFromContext:_ctx];