+2005-07-14 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoAppointmentFolder.m: moved +globallyUniqueObjectId method to
+ SOGoFolder.m baseclass (v0.9.42)
+
2005-07-13 Helge Hess <helge.hess@opengroupware.org>
* SOGoAppointmentFolder.m: added a method to determine the resource
NSMutableDictionary *uidToFilename;
}
-+ (NSString *)globallyUniqueObjectId;
-
/* selection */
- (NSArray *)calendarUIDs;
#include <NGiCal/NGiCal.h>
#include <NGExtensions/NGCalendarDateRange.h>
#include "common.h"
-#include <unistd.h>
-#include <stdlib.h>
#if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY
@interface NSDate(UsedPrivates)
MET = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
}
-+ (NSString *)globallyUniqueObjectId {
- /*
- 4C08AE1A-A808-11D8-AC5A-000393BBAFF6
- SOGo-Web-28273-18283-288182
- printf( "%x", *(int *) &f);
- */
- static int pid = 0;
- static int sequence = 0;
- static float rndm = 0;
- float f;
-
- if (pid == 0) { /* break if we fork ;-) */
- pid = getpid();
- rndm = random();
- }
- sequence++;
- f = [[NSDate date] timeIntervalSince1970];
- return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
- pid, *(int *)&f, sequence++, random];
-}
-
- (void)dealloc {
[self->uidToFilename release];
[super dealloc];
# Version file
-SUBMINOR_VERSION:=40
+SUBMINOR_VERSION:=42
+# v0.9.42 requires libSOGo v0.9.54
# v0.9.32 requires libGDLContentStore v4.5.26
# v0.9.28 requires libNGiCal v4.5.47
# v0.9.26 requires libSOGo v0.9.30
+2005-07-14 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoContactFolder.m: use +globallyUniqueObjectId method from
+ SOGoFolder.m baseclass (v0.9.12)
+
2005-07-13 Helge Hess <helge.hess@opengroupware.org>
* SOGoContactObject.m: hardened against vCard content (v0.9.11)
/*
- Copyright (C) 2004 SKYRIX Software AG
+ Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-// $Id$
#ifndef __Contacts_SOGoContactFolder_H__
#define __Contacts_SOGoContactFolder_H__
{
}
-+ (NSString *)globallyUniqueObjectId;
-
/* fetching */
- (NSArray *)fetchCoreInfos;
@implementation SOGoContactFolder
-+ (NSString *)globallyUniqueObjectId {
- /*
- 4C08AE1A-A808-11D8-AC5A-000393BBAFF6
- SOGo-Web-28273-18283-288182
- printf( "%x", *(int *) &f);
- */
- static int pid = 0;
- static int sequence = 0;
- static float rndm = 0;
- float f;
-
- if (pid == 0) { /* break if we fork ;-) */
- pid = getpid();
- rndm = random();
- }
- sequence++;
- f = [[NSDate date] timeIntervalSince1970];
- return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
- pid, *(int *)&f, sequence++, random];
-}
-
-- (void)dealloc {
- [super dealloc];
-}
-
/* name lookup */
- (BOOL)isValidContactName:(NSString *)_key {
- (id)valueForKey:(NSString *)_key {
id value;
-
+
if ((value = [[self record] valueForKey:_key]) != nil)
return value;
# version file
-SUBMINOR_VERSION:=11
+SUBMINOR_VERSION:=12
-# v0.9.9 requires libGDLContentStore v4.5.26
-# v0.9.5 requires libNGExtensions v4.5.136
+# v0.9.12 requires libSOGo v0.9.54
+# v0.9.9 requires libGDLContentStore v4.5.26
+# v0.9.5 requires libNGExtensions v4.5.136
2005-07-14 Helge Hess <helge.hess@opengroupware.org>
+ * v0.9.54
+
+ * SOGoContentObject.m: added support for special 'new' key (server will
+ assign a name and add the new location in a special response header)
+
+ * SOGoFolder.m: added +globallyUniqueObjectId (previously the method
+ was duplicated in each subclass)
+
* SOGoContentObject.m: added transactionally save etag-checks in PUT
(use the etag value as the baseVersion in the content store)
(v0.9.53)
/*
- Copyright (C) 2004 SKYRIX Software AG
+ Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-// $Id$
#ifndef __SOGoAppointment_H_
#define __SOGoAppointment_H_
*/
#include "SOGoContentObject.h"
+#include "SOGoFolder.h"
#include <NGObjWeb/WEClientCapabilities.h>
#include "common.h"
#include <GDLContentStore/GCSFolder.h>
WORequest *rq;
NSException *error;
unsigned int baseVersion;
- id etag;
+ id etag, tmp;
+ BOOL needsLocation;
if ((error = [self matchesRequestConditionInContext:_ctx]) != nil)
return error;
rq = [_ctx request];
+ /* check whether its a request to the 'special' 'new' location */
+ /*
+ Note: this is kinda hack. The OGo ZideStore detects writes to 'new' as
+ object creations and will assign a server side identifier. Most
+ current GroupDAV clients rely on this behaviour, so we reproduce it
+ here.
+ A correct client would loop until it has a name which doesn't not
+ yet exist (by using if-none-match).
+ */
+ needsLocation = NO;
+ tmp = [[self nameInContainer] stringByDeletingPathExtension];
+ if ([tmp isEqualToString:@"new"]) {
+ tmp = [[[self container] class] globallyUniqueObjectId];
+ needsLocation = YES;
+
+ [self debugWithFormat:
+ @"reassigned a new location for special new-location: %@", tmp];
+
+ /* kinda dangerous */
+ ASSIGNCOPY(self->nameInContainer, tmp);
+ ASSIGN(self->ocsPath, nil);
+ }
+
/* determine base version from etag in if-match header */
/*
Note: The -matchesRequestConditionInContext: already checks whether the
commit.
(between the check and the update a change could have been done)
*/
- etag = [rq headerForKey:@"if-match"];
- etag = [self parseETagList:etag];
- if ([etag count] > 0) {
- if ([etag count] > 1) {
+ tmp = [rq headerForKey:@"if-match"];
+ tmp = [self parseETagList:tmp];
+ etag = nil;
+ if ([tmp count] > 0) {
+ if ([tmp count] > 1) {
/*
Note: we would have to attempt a save for _each_ of the etags being
passed in! In practice most WebDAV clients submit exactly one
*/
[self warnWithFormat:
@"Got multiple if-match etags from client, only attempting to "
- @"save with the first: %@", etag];
+ @"save with the first: %@", tmp];
}
- etag = [etag objectAtIndex:0];
+ etag = [tmp objectAtIndex:0];
}
baseVersion = ([etag length] > 0)
? [etag unsignedIntValue]
baseVersion:baseVersion]) != nil)
return error;
- // TODO: this should be automatic if we return nil?
+ /* setup response */
+
+ // TODO: this should be automatic in the SoDispatcher if we return nil?
[[_ctx response] setStatus:201 /* Created */];
if ((etag = [self davEntityTag]) != nil)
[[_ctx response] setHeader:etag forKey:@"etag"];
+
+ if (needsLocation) {
+ [[_ctx response] setHeader:[self baseURLInContext:_ctx]
+ forKey:@"location"];
+ }
+
return [_ctx response];
}
GCSFolder *ocsFolder;
}
++ (NSString *)globallyUniqueObjectId;
+
/* accessors */
- (void)setOCSPath:(NSString *)_Path;
#include "common.h"
#include <GDLContentStore/GCSFolderManager.h>
#include <GDLContentStore/GCSFolder.h>
+#include <unistd.h>
+#include <stdlib.h>
@implementation SOGoFolder
NSStringFromClass([self superclass]), [super version]);
}
++ (NSString *)globallyUniqueObjectId {
+ /*
+ 4C08AE1A-A808-11D8-AC5A-000393BBAFF6
+ SOGo-Web-28273-18283-288182
+ printf( "%x", *(int *) &f);
+ */
+ static int pid = 0;
+ static int sequence = 0;
+ static float rndm = 0;
+ float f;
+
+ if (pid == 0) { /* break if we fork ;-) */
+ pid = getpid();
+ rndm = random();
+ }
+ sequence++;
+ f = [[NSDate date] timeIntervalSince1970];
+ return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
+ pid, *(int *)&f, sequence++, random];
+}
+
- (void)dealloc {
[self->ocsFolder release];
[self->ocsPath release];
# version file
-SUBMINOR_VERSION:=53
+SUBMINOR_VERSION:=54
# v0.9.50 requires libGDLContentStore v4.5.30
# v0.9.34 requires libGDLContentStore v4.5.26