//
// JABDirectory.m
// ChatServer/jabber_autobuddy
//
// Created by peralta on 7/18/08.
// Copyright 2008 Apple. All rights reserved.
//
#import "JABDirectory.h"
#import <OpenDirectory/NSOpenDirectory.h>
@implementation JABDirectory
@synthesize searchScope = _searchScope;
@synthesize directorySession = _directorySession;
@synthesize directoryNode = _directoryNode;
//--------------------------------------------------------------------------------
+ (id) jabDirectory
{
return [[[self alloc] initWithScope: DIRECTORYSCOPE_UNDEFINED] autorelease];
}
//--------------------------------------------------------------------------------
+ (id) jabDirectoryWithScope: (NSInteger) iScope
{
return [[[self alloc] initWithScope: iScope] autorelease];
}
//--------------------------------------------------------------------------------
+ (NSString *) getRecordName: (NSObject *) aRec
{
// Helper function for abstracting the different record classes
// between DSOjbCWrappers and NSOpenDirectory:
// - For 10.6 and later, aRec is an ODRecord
// - For 10.5 and earlier, aRec is an NSDictionary
ODRecord *odRec = (ODRecord *) aRec;
return [odRec recordName];
}
//--------------------------------------------------------------------------------
+ (NSString *) getAttributeValue: (NSString *) attribKey fromRecord: (NSObject *) aRec
{
// Helper function for abstracting the different record classes
// between DSOjbCWrappers and NSOpenDirectory:
// - For 10.6 and later, aRec is an ODRecord
// - For 10.5 and earlier, aRec is an NSDictionary
NSArray *attrVals = nil;
ODRecord *odRec = (ODRecord *) aRec;
NSError *odErr = nil;
attrVals = [odRec valuesForAttribute: attribKey error: &odErr];
if (nil == attrVals) return nil; // attribute not found in record
return (0 < [attrVals count]) ? [attrVals objectAtIndex: 0] : nil;
}
#pragma mark -
//--------------------------------------------------------------------------------
- (id) initWithScope: (NSInteger) iScope
{
self = [super init];
[self openNodeWithScope: iScope];
return self;
}
- (void) dealloc
{
[self closeNode];
[super dealloc];
}
#pragma mark -
//--------------------------------------------------------------------------------
- (void) openLocalNode
{
[self openNodeWithScope: DIRECTORYSCOPE_LOCAL];
}
//--------------------------------------------------------------------------------
- (void) openSearchNode
{
[self openNodeWithScope: DIRECTORYSCOPE_SEARCH];
}
//--------------------------------------------------------------------------------
- (void) openNodeWithScope: (NSInteger) iScope
{
// Open a new directoryNode based on the requested scope (local or search)
// WARNING: There is only one active directoryNode instance. Opening a
// new directoryNode will terminate any existing node!
//
// NOTE: Callers should use [SMPServer closeDirectoryNode] to terminate
// the active directoryNode as soon as DS interaction is complete
// to insure that all DS-allocated resources are released.
[self closeNode]; // terminate active node (if any)
self.searchScope = iScope; // define the scope of a new DS node
// Create a DS node of the selected scope
do { // not a loop
if (DIRECTORYSCOPE_UNDEFINED == iScope)
break; // scope undefined -- nothing to open
// Make a connection to the DS service
self.directorySession = [ODSession defaultSession];
if (nil == self.directorySession)
break; // can't access DS -- abort
// Create the appropriately scoped directory node
ODNode *aNode = nil;
switch (iScope) {
case DIRECTORYSCOPE_SEARCH:
aNode = [ODNode nodeWithSession: self.directorySession
type: kODNodeTypeAuthentication
error: nil];
break;
case DIRECTORYSCOPE_LOCAL:
aNode = [ODNode nodeWithSession: self.directorySession
type: kODNodeTypeLocalNodes
error: nil];
break;
default: ; // DIRECTORYSCOPE_UNDEFINED
} // switch
self.directoryNode = aNode;
} while (0); // not a loop
}
//--------------------------------------------------------------------------------
- (void) closeNode
{
self.directoryNode = nil;
self.directorySession = nil;
self.searchScope = DIRECTORYSCOPE_UNDEFINED;
}
//--------------------------------------------------------------------------------
- (BOOL) isNodeOpen
{
return (nil != self.directoryNode);
}
#pragma mark -
//--------------------------------------------------------------------------------
- (NSString *) findAttribute: (NSString *) attrName inRecord: (NSString *) recName ofType: (NSString *) recType
{
// Search the current scope for a attribute in the specified record.
NSString *attribText = nil;
do { // not a loop
// Read legacy config data from OpenDirectory
if (![self isNodeOpen])
break; // no open node -- abort
NSError *queryErr = nil;
ODQuery *aQuery = [ODQuery queryWithNode: self.directoryNode
forRecordTypes: recType
attribute: attrName
matchType: kODMatchAny
queryValues: nil // (id) inQueryValueOrList - what's this?
returnAttributes: attrName
maximumResults: 0
error: &queryErr];
NSArray *recList = [aQuery resultsAllowingPartial: NO error: &queryErr];
attribText = [recList objectAtIndex: 0];
} while (0); // not a loop
return attribText;
}
//--------------------------------------------------------------------------------
- (NSArray *) findAllRecordsOfType: (NSString *) recType
{
// Search the current scope for all records matching the specified type.
NSArray *recList = nil;
do { // not a loop
if (![self isNodeOpen])
break; // no open node -- abort
NSError *queryErr = nil;
ODQuery *aQuery = [ODQuery queryWithNode: self.directoryNode
forRecordTypes: recType
attribute: nil
matchType: kODMatchAny
queryValues: nil // (id) inQueryValueOrList - what's this?
returnAttributes: nil
maximumResults: 0
error: &queryErr];
recList = [aQuery resultsAllowingPartial: NO error: &queryErr];
} while (0); // not a loop
return recList;
}
@end