sogo/SoObjects/Contacts/SOGoContactSourceFolder.m
Wolfgang Sourdeau f19bba7292 Monotone-Parent: c46d8b7dd8119925eededd812de04ae71f5c1d6d
Monotone-Revision: e78fc689c78de581aaf34ccdcebebddeb142c5b3

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2010-08-12T14:02:21
Monotone-Branch: ca.inverse.sogo
2010-08-12 14:02:21 +00:00

330 lines
8.2 KiB
Objective-C

/* SOGoContactSourceFolder.m - this file is part of SOGo
*
* Copyright (C) 2006-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
#import <NGObjWeb/SoObject.h>
#import <NGObjWeb/SoSelectorInvocation.h>
#import <NGObjWeb/SoUser.h>
#import <NGExtensions/NSString+misc.h>
#import <EOControl/EOSortOrdering.h>
#import <SaxObjC/XMLNamespaces.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import "SOGoContactLDIFEntry.h"
#import "SOGoContactSourceFolder.h"
@class WOContext;
@implementation SOGoContactSourceFolder
+ (id) folderWithName: (NSString *) aName
andDisplayName: (NSString *) aDisplayName
inContainer: (id) aContainer
{
id folder;
folder = [[self alloc] initWithName: aName
andDisplayName: aDisplayName
inContainer: aContainer];
[folder autorelease];
return folder;
}
- (id) init
{
if ((self = [super init]))
{
childRecords = [NSMutableDictionary new];
source = nil;
}
return self;
}
- (id) initWithName: (NSString *) newName
andDisplayName: (NSString *) newDisplayName
inContainer: (id) newContainer
{
if ((self = [self initWithName: newName
inContainer: newContainer]))
{
if (![newDisplayName length])
newDisplayName = newName;
ASSIGN (displayName, newDisplayName);
}
return self;
}
- (void) dealloc
{
[childRecords release];
[source release];
[super dealloc];
}
- (void) setSource: (id) newSource
{
ASSIGN (source, newSource);
}
- (NSString *) groupDavResourceType
{
return @"vcard-collection";
}
- (NSArray *) davResourceType
{
NSMutableArray *resourceType;
NSArray *cardDavCollection;
cardDavCollection
= [NSArray arrayWithObjects: @"addressbook",
@"urn:ietf:params:xml:ns:carddav", nil];
resourceType = [NSMutableArray arrayWithArray: [super davResourceType]];
[resourceType addObject: cardDavCollection];
return resourceType;
}
- (id) lookupName: (NSString *) objectName
inContext: (WOContext *) lookupContext
acquire: (BOOL) acquire
{
NSDictionary *ldifEntry;
id obj;
/* first check attributes directly bound to the application */
obj = [super lookupName: objectName inContext: lookupContext acquire: NO];
if (!obj)
{
ldifEntry = [childRecords objectForKey: objectName];
if (!ldifEntry)
{
ldifEntry = [source lookupContactEntry: objectName];
if (ldifEntry)
[childRecords setObject: ldifEntry forKey: objectName];
}
if (ldifEntry)
obj = [SOGoContactLDIFEntry contactEntryWithName: objectName
withLDIFEntry: ldifEntry
inContainer: self];
else
obj = [NSException exceptionWithHTTPStatus: 404];
}
return obj;
}
- (NSArray *) toOneRelationshipKeys
{
return [source allEntryIDs];
}
- (NSDictionary *) _flattenedRecord: (NSDictionary *) oldRecord
{
NSMutableDictionary *newRecord;
NSString *data;
newRecord = [NSMutableDictionary dictionaryWithCapacity: 8];
[newRecord setObject: [oldRecord objectForKey: @"c_uid"]
forKey: @"c_uid"];
[newRecord setObject: [oldRecord objectForKey: @"c_name"]
forKey: @"c_name"];
data = [oldRecord objectForKey: @"displayname"];
if (!data)
data = [oldRecord objectForKey: @"c_cn"];
if (!data)
data = @"";
[newRecord setObject: data forKey: @"c_cn"];
data = [oldRecord objectForKey: @"mail"];
if (!data)
data = @"";
[newRecord setObject: data forKey: @"c_mail"];
data = [oldRecord objectForKey: @"nsaimid"];
if (![data length])
data = [oldRecord objectForKey: @"nscpaimscreenname"];
if (![data length])
data = @"";
[newRecord setObject: data forKey: @"c_screenname"];
data = [oldRecord objectForKey: @"o"];
if (!data)
data = @"";
[newRecord setObject: data forKey: @"c_o"];
data = [oldRecord objectForKey: @"telephonenumber"];
if (![data length])
data = [oldRecord objectForKey: @"cellphone"];
if (![data length])
data = [oldRecord objectForKey: @"homephone"];
if (![data length])
data = @"";
[newRecord setObject: data forKey: @"c_telephonenumber"];
// Custom attribute for group-lookups. See LDAPSource.m where
// it's set.
data = [oldRecord objectForKey: @"isGroup"];
if (data)
[newRecord setObject: data forKey: @"isGroup"];
data = [oldRecord objectForKey: @"c_info"];
if ([data length] > 0)
[newRecord setObject: data forKey: @"contactInfo"];
return newRecord;
}
- (NSArray *) _flattenedRecords: (NSArray *) records
{
NSMutableArray *newRecords;
NSEnumerator *oldRecords;
NSDictionary *oldRecord;
newRecords = [NSMutableArray arrayWithCapacity: [records count]];
oldRecords = [records objectEnumerator];
while ((oldRecord = [oldRecords nextObject]))
[newRecords addObject: [self _flattenedRecord: oldRecord]];
return newRecords;
}
/* This method returns the entry corresponding to the name passed as
parameter. */
- (NSDictionary *) lookupContactWithName: (NSString *) aName
{
NSDictionary *record;
if (aName && [aName length] > 0)
record = [self _flattenedRecord: [source lookupContactEntry: aName]];
else
record = nil;
return record;
}
- (NSArray *) lookupContactsWithFilter: (NSString *) filter
sortBy: (NSString *) sortKey
ordering: (NSComparisonResult) sortOrdering
{
NSArray *records, *result;
EOSortOrdering *ordering;
result = nil;
if (filter && [filter length] > 0)
{
records = [source fetchContactsMatching: filter];
[childRecords setObjects: records
forKeys: [records objectsForKey: @"c_name"
notFoundMarker: nil]];
records = [self _flattenedRecords: records];
ordering
= [EOSortOrdering sortOrderingWithKey: sortKey
selector: ((sortOrdering == NSOrderedDescending)
? EOCompareCaseInsensitiveDescending
: EOCompareCaseInsensitiveAscending)];
result
= [records sortedArrayUsingKeyOrderArray:
[NSArray arrayWithObject: ordering]];
}
return result;
}
- (NSString *) davDisplayName
{
return displayName;
}
- (BOOL) isFolderish
{
return YES;
}
/* folder type */
- (NSString *) folderType
{
return @"Contact";
}
- (NSString *) outlookFolderClass
{
return @"IPF.Contact";
}
/* sorting */
- (NSComparisonResult) compare: (id) otherFolder
{
NSComparisonResult comparison;
if ([NSStringFromClass([otherFolder class])
isEqualToString: @"SOGoContactGCSFolder"])
comparison = NSOrderedDescending;
else
comparison
= [[self displayName]
localizedCaseInsensitiveCompare: [otherFolder displayName]];
return comparison;
}
/* acls */
- (NSString *) ownerInContext: (WOContext *) noContext
{
return @"nobody";
}
- (NSArray *) subscriptionRoles
{
return [NSArray arrayWithObject: SoRole_Authenticated];
}
/* TODO: this might change one day when we support LDAP acls */
- (NSArray *) aclsForUser: (NSString *) uid
{
return nil;
}
@end