JABDirectory.m   [plain text]


//
//  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