02111-1307, USA.
*/
-#import <unistd.h>
-#import <stdlib.h>
-
#import <Foundation/NSArray.h>
+#import <Foundation/NSDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
+#import <Foundation/NSKeyValueCoding.h>
#import <Foundation/NSURL.h>
+#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoObject.h>
#import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/SoSelectorInvocation.h>
#import <NGExtensions/NSObject+Logs.h>
#import <EOControl/EOQualifier.h>
#import <GDLAccess/EOAdaptorChannel.h>
+#import <GDLContentStore/GCSChannelManager.h>
#import <GDLContentStore/GCSFolderManager.h>
#import <GDLContentStore/GCSFolder.h>
#import <GDLContentStore/GCSFolderType.h>
+#import <GDLContentStore/NSURL+GCS.h>
#import <SaxObjC/XMLNamespaces.h>
+#import "NSArray+Utilities.h"
#import "NSString+Utilities.h"
#import "SOGoPermissions.h"
NSStringFromClass([self superclass]), [super version]);
}
-+ (NSString *) globallyUniqueObjectId
++ (id) folderWithSubscriptionReference: (NSString *) reference
+ inContainer: (id) aContainer
{
- /*
- 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];
+ id newFolder;
+ NSArray *elements, *pathElements;
+ NSString *ocsPath, *objectPath, *owner, *ocsName, *folderName;
+
+ elements = [reference componentsSeparatedByString: @":"];
+ owner = [elements objectAtIndex: 0];
+ objectPath = [elements objectAtIndex: 1];
+ pathElements = [objectPath componentsSeparatedByString: @"/"];
+ if ([pathElements count] > 1)
+ ocsName = [pathElements objectAtIndex: 1];
+ else
+ ocsName = @"personal";
+
+ ocsPath = [NSString stringWithFormat: @"/Users/%@/%@/%@",
+ owner, [pathElements objectAtIndex: 0], ocsName];
+ folderName = [NSString stringWithFormat: @"%@_%@", owner, ocsName];
+ newFolder = [[self alloc] initWithName: folderName
+ inContainer: aContainer];
+ [newFolder setOCSPath: ocsPath];
+ [newFolder setOwner: owner];
+
+ return newFolder;
}
- (id) init
{
if ((self = [super init]))
{
+ displayName = nil;
ocsPath = nil;
ocsFolder = nil;
aclCache = [NSMutableDictionary new];
[ocsFolder release];
[ocsPath release];
[aclCache release];
+ [displayName release];
[super dealloc];
}
- (void) setOCSPath: (NSString *) _path
{
- if ([ocsPath isEqualToString:_path])
- return;
-
- if (ocsPath)
- [self warnWithFormat:@"GCS path is already set! '%@'", _path];
-
- ASSIGNCOPY(ocsPath, _path);
+ if (![ocsPath isEqualToString:_path])
+ {
+ if (ocsPath)
+ [self warnWithFormat: @"GCS path is already set! '%@'", _path];
+ ASSIGN (ocsPath, _path);
+ }
}
- (NSString *) ocsPath
static GCSFolderManager *folderManager = nil;
if (!folderManager)
- {
- folderManager = [GCSFolderManager defaultFolderManager];
- [folderManager setFolderNamePrefix: @"SOGo"];
- }
+ folderManager = [GCSFolderManager defaultFolderManager];
return folderManager;
}
- (BOOL) folderIsMandatory
{
- [self subclassResponsibility: _cmd];
+ return [nameInContainer isEqualToString: @"personal"];
+}
- return NO;
+- (void) _setDisplayNameFromRow: (NSDictionary *) row
+{
+ NSString *currentLogin, *ownerLogin;
+ NSDictionary *ownerIdentity;
+
+ displayName
+ = [NSMutableString stringWithString: [row objectForKey: @"c_foldername"]];
+ currentLogin = [[context activeUser] login];
+ ownerLogin = [self ownerInContext: context];
+ if (![currentLogin isEqualToString: ownerLogin])
+ {
+ ownerIdentity = [[SOGoUser userWithLogin: ownerLogin roles: nil]
+ primaryIdentity];
+ [displayName appendFormat: @" (%@ <%@>)",
+ [ownerIdentity objectForKey: @"fullName"],
+ [ownerIdentity objectForKey: @"email"]];
+ }
+}
+
+- (void) _fetchDisplayName
+{
+ GCSChannelManager *cm;
+ EOAdaptorChannel *fc;
+ NSURL *folderLocation;
+ NSString *sql;
+ NSArray *attrs;
+ NSDictionary *row;
+
+ cm = [GCSChannelManager defaultChannelManager];
+ folderLocation
+ = [[GCSFolderManager defaultFolderManager] folderInfoLocation];
+ fc = [cm acquireOpenChannelForURL: folderLocation];
+ if (fc)
+ {
+ sql
+ = [NSString stringWithFormat: (@"SELECT c_foldername FROM %@"
+ @" WHERE c_path = '%@'"),
+ [folderLocation gcsTableName], ocsPath];
+ [fc evaluateExpressionX: sql];
+ attrs = [fc describeResults: NO];
+ row = [fc fetchAttributes: attrs withZone: NULL];
+ if (row)
+ [self _setDisplayNameFromRow: row];
+ [fc cancelFetch];
+ [cm releaseChannel: fc];
+ }
+}
+
+- (void) setDisplayName: (NSString *) newDisplayName
+{
+ ASSIGN (displayName, newDisplayName);
+}
+
+- (NSString *) displayName
+{
+ if (!displayName)
+ [self _fetchDisplayName];
+
+ return displayName;
+}
+
+- (NSString *) davDisplayName
+{
+ return [self displayName];
}
- (GCSFolder *) ocsFolder
{
NSException *result;
+// [self dieHard];
result = [[self folderManager] createFolderOfType: [self folderType]
+ withName: displayName
atPath: ocsPath];
return (result == nil);
- (NSException *) delete
{
- return [[self folderManager] deleteFolderAtPath: ocsPath];
+ NSException *error;
+
+ if ([nameInContainer isEqualToString: @"personal"])
+ error = [NSException exceptionWithHTTPStatus: 403
+ reason: @"folder 'personal' cannot be deleted"];
+ else
+ error = [[self folderManager] deleteFolderAtPath: ocsPath];
+
+ return error;
+}
+
+- (void) renameTo: (NSString *) newName
+{
+ GCSChannelManager *cm;
+ EOAdaptorChannel *fc;
+ NSURL *folderLocation;
+ NSString *sql;
+
+ [displayName release];
+ displayName = nil;
+
+ cm = [GCSChannelManager defaultChannelManager];
+ folderLocation
+ = [[GCSFolderManager defaultFolderManager] folderInfoLocation];
+ fc = [cm acquireOpenChannelForURL: folderLocation];
+ if (fc)
+ {
+ sql
+ = [NSString stringWithFormat: (@"UPDATE %@ SET c_foldername = '%@'"
+ @" WHERE c_path = '%@'"),
+ [folderLocation gcsTableName], newName, ocsPath];
+ [fc evaluateExpressionX: sql];
+ [cm releaseChannel: fc];
+// sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
+// uidColumnName, [self uid]];
+ }
}
- (NSArray *) fetchContentObjectNames
}
if ([records isKindOfClass: [NSException class]])
return records;
- return [records valueForKey: @"c_name"];
+ return [records objectsForKey: @"c_name"];
}
- (BOOL) nameExistsInFolder: (NSString *) objectName
/* acls */
- (NSArray *) aclUsers
{
- return [self aclUsersForObjectAtPath: [self pathArrayToSoObject]];
+ return [self aclUsersForObjectAtPath: [self pathArrayToSOGoObject]];
}
- (NSArray *) aclsForUser: (NSString *) uid
acls = [NSMutableArray array];
ownAcls = [self aclsForUser: uid
- forObjectAtPath: [self pathArrayToSoObject]];
+ forObjectAtPath: [self pathArrayToSOGoObject]];
[acls addObjectsFromArray: ownAcls];
if ([container respondsToSelector: @selector (aclsForUser:)])
{
{
return [self setRoles: roles
forUser: uid
- forObjectAtPath: [self pathArrayToSoObject]];
+ forObjectAtPath: [self pathArrayToSOGoObject]];
}
- (void) removeAclsForUsers: (NSArray *) users
{
return [self removeAclsForUsers: users
- forObjectAtPath: [self pathArrayToSoObject]];
+ forObjectAtPath: [self pathArrayToSOGoObject]];
}
- (NSString *) defaultUserID