2 Copyright (C) 2004-2005 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 "UIxContactEditorBase.h"
23 #include <Contacts/SOGoContactObject.h>
24 #include <Contacts/SOGoContactFolder.h>
27 @implementation UIxContactEditorBase
30 if ((self = [super init])) {
31 self->snapshot = [[NSMutableDictionary alloc] initWithCapacity:16];
37 [self->snapshot release];
38 [self->anaisCN release];
39 [self->errorText release];
40 [self->contentString release];
46 - (void)setContentString:(NSString *)_cstr {
47 ASSIGNCOPY(self->contentString, _cstr);
49 - (NSString *)contentString {
50 return self->contentString;
53 - (NSString *)contentStringTemplate {
54 return @"{}"; /* empty property list */
57 - (NSMutableDictionary *)snapshot {
58 return self->snapshot;
61 - (void)setErrorText:(NSString *)_txt {
62 ASSIGNCOPY(self->errorText, _txt);
64 - (NSString *)errorText {
65 return self->errorText;
68 - (BOOL)hasErrorText {
69 return [self->errorText length] > 0 ? YES : NO;
73 - (void)setAnaisCN:(NSString *)_txt {
74 ASSIGNCOPY(self->anaisCN, _txt);
76 - (NSString *)anaisCN {
81 /* load/store content format */
83 - (void)loadValuesFromContentString:(NSString *)_s {
86 if ([_s hasPrefix:@"BEGIN:VCARD"]) {
87 // TODO: load vCard values
88 [self errorWithFormat:@"Editing of vCard's is not yet supported!"];
92 if ((plist = [_s propertyList]) == nil) {
93 [self errorWithFormat:@"could not parse content string!"];
97 [self->snapshot removeAllObjects];
98 [self->snapshot addEntriesFromDictionary:plist];
101 - (void)_fixupSnapshot {
102 // TODO: perform sanity checking, eg build CN on demand
103 NSString *cn, *gn, *sn;
105 cn = [self->snapshot objectForKey:@"cn"];
106 gn = [self->snapshot objectForKey:@"givenName"];
107 sn = [self->snapshot objectForKey:@"sn"];
109 if (![sn isNotNull] || [sn length] == 0)
111 if (![cn isNotNull] || [cn length] == 0)
118 // TODO: need a better name parser here
121 r = [cn rangeOfString:@" "];
123 ? [cn substringFromIndex:(r.location + r.length)]
126 [self->snapshot setObject:sn forKey:@"sn"];
128 if ([self->anaisCN length] > 0 )
130 else if (sn == nil && gn == nil)
137 cn = [[gn stringByAppendingString:@" "] stringByAppendingString:sn];
138 [self->snapshot setObject:cn forKey:@"cn"];
141 - (void)saveValuesIntoRecord:(NSMutableDictionary *)_record {
142 [self _fixupSnapshot];
143 [_record addEntriesFromDictionary:[self snapshot]];
148 - (NSString *)_completeURIForMethod:(NSString *)_method {
149 // TODO: this is a DUP of UIxAppointmentEditor
153 uri = [[[self context] request] uri];
155 /* first: identify query parameters */
156 r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
158 uri = [uri substringToIndex:r.location];
160 /* next: append trailing slash */
161 if (![uri hasSuffix:@"/"])
162 uri = [uri stringByAppendingString:@"/"];
164 /* next: append method */
165 uri = [uri stringByAppendingString:_method];
167 /* next: append query parameters */
168 return [self completeHrefForMethod:uri];
173 - (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
177 - (id<WOActionResults>)defaultAction {
178 // TODO: very similiar to apt-editor (apt editor would need to use std names
181 /* load iCalendar file */
183 c = [[self clientObject] contentAsString];
184 if ([c length] == 0) /* a new contact */
185 c = [self contentStringTemplate];
187 [self setContentString:c];
188 [self loadValuesFromContentString:c];
193 - (BOOL)isWriteableClientObject {
194 return [[self clientObject]
195 respondsToSelector:@selector(saveContentString:)];
198 - (NSString *)viewActionName {
199 /* this is overridden in the mail based contacts UI to redirect to tb.edit */
202 - (NSString *)editActionName {
203 /* this is overridden in the mail based contacts UI to redirect to tb.edit */
209 NSString *recstr, *uri;
212 if (![self isWriteableClientObject]) {
213 return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
214 reason:@"method cannot be invoked on "
215 @"the specified object"];
218 if ((record = [self contentString]) == nil) {
219 [self setErrorText:@"Missing object content!"]; // localize
222 record = [[[record propertyList] mutableCopy] autorelease];
224 [self setErrorText:@"Invalid property list data ..."]; // localize
228 [self saveValuesIntoRecord:record];
230 // TODO: directly hacking the content, hm, not so nice or reasonable?
231 recstr = [record description]; // make plist
232 ex = [[self clientObject] saveContentString:recstr];
234 [self setErrorText:[ex reason]];
238 uri = ([(uri = [self viewActionName]) length] > 0)
239 ? [self viewActionName] : @"..";
240 uri = [self _completeURIForMethod:uri];
241 return [self redirectToLocation:uri];
245 [self logWithFormat:@"test ..."];
250 // TODO: this is almost a DUP of UIxAppointmentEditor
252 This method creates a unique ID and redirects to the "edit" method on the
254 It is actually a folder method and should be defined on the folder.
256 Note: 'clientObject' is the SOGoAppointmentFolder!
257 Update: remember that there are group folders as well.
259 NSString *uri, *objectId, *nextMethod;
261 objectId = [NSClassFromString(@"SOGoContactFolder") globallyUniqueObjectId];
262 if ([objectId length] == 0) {
263 return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
264 reason:@"could not create a unique ID"];
267 nextMethod = [NSString stringWithFormat:@"../%@/%@",
268 objectId, [self editActionName]];
269 uri = [self _completeURIForMethod:nextMethod];
270 return [self redirectToLocation:uri];
273 @end /* UIxContactEditorBase */