/*!
@header FTFileStoreTEST
@abstract Module of FT
@availability OS X, GNUstep
@copyright 2004, 2005 Free Software Foundation, Inc.
Author: Oliver Langer
This program 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 of the License, or
(at your option) any later version.
This program 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; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------
Modification history
13.11.05 ola initial version
-------------------------------------------------------------------------
*/
#include
#include
@implementation FTFileStoreTEST
- (NSString *) createPathOfFilename: (NSString *) aFilename {
NSArray *pathComponents = [aFilename pathComponents];
NSMutableString *toReturn = nil;
int slashCounter = 0;
int i;
toReturn = [[NSMutableString alloc] init];
for( i = 0; i < [pathComponents count]-1; i++ ) {
if( slashCounter > 1 ) {
[toReturn appendString: @"/"];
} else {
slashCounter++;
}
[toReturn appendString: [pathComponents objectAtIndex: i]];
}
return toReturn;
}
- (NSString *) popPathStack: (NSMutableArray *) aPathStack
untilFoundPath: (NSString *) aPath {
unsigned int index;
NSString *topElement = nil;
index = [aPathStack indexOfObject: aPath];
if( NSNotFound == index ) {
NSLog( @"Path \"%@\" not found in stack of paths!",
aPath );
topElement = nil;
} else {
// now pop all elements at a higher index than "index":
int count = [aPathStack count] - index - 1;
for( ; count > 0; count-- ) {
[aPathStack removeObjectAtIndex: index+1];
}
topElement = [aPathStack objectAtIndex: [aPathStack count]-1];
}
return topElement;
}
- iterateBeginingAtPath: (NSString *) aPath
excludeSubDirectories: (NSSet *) excludes
sendingEventsTo: (id ) eventHandler {
EC_AUTORELEASEPOOL_BEGIN
NSFileManager *fileManager = [NSFileManager defaultManager];
NSEnumerator *directoryContent
= [fileManager enumeratorAtPath: aPath];
NSString *filename;
NSMutableArray *directoryStack
= [[[NSMutableArray alloc] init] autorelease];
NSString *currentDirectory = aPath;
NSLog( @"FTFileStoreTEST::iterate: Beginning with path: %@", aPath );
[directoryStack addObject: currentDirectory];
[eventHandler addDirectory: currentDirectory
ofParentDirectory: nil];
while( (filename = [directoryContent nextObject]) ) {
NSString *absoluteFileName = [[NSString alloc]
initWithFormat: @"%@/%@", aPath, filename];
BOOL ignoreFile = NO;
if( nil != excludes ) {
NSScanner *scanner = nil;
NSEnumerator *excludeDirs;
NSString *excludeDir;
excludeDirs = [excludes objectEnumerator];
while( (excludeDir = [excludeDirs nextObject]) ) {
scanner = [[NSScanner alloc] initWithString: filename];
ignoreFile = [scanner scanString: excludeDir intoString: NULL];
[scanner release];
if( ignoreFile ) {
break;
}
}
}
if( ignoreFile ) {
NSLog( @"FTFileStoreTEST::iterate: Ignoring file: %@", absoluteFileName );
} else {
NSLog( @"FTFileStoreTEST::iterate: Next file is: %@", absoluteFileName );
BOOL isADirectory;
/* if it is a directory, then push it on the stack.
* if is is a file then check to which directory it belongs
*/
[fileManager fileExistsAtPath: absoluteFileName isDirectory: &isADirectory];
if( isADirectory ) {
// a directory, so push it:
NSLog( @"FTFileStoreTEST::iterate: %@ is a directory", absoluteFileName );
[directoryStack addObject: absoluteFileName];
[eventHandler addDirectory: absoluteFileName
ofParentDirectory: currentDirectory];
currentDirectory = absoluteFileName;
} else {
NSString *pathOfCurrentFile;
NSLog( @"FTFileStoreTEST::iterate: %@ is a file",
absoluteFileName );
pathOfCurrentFile = [self createPathOfFilename: absoluteFileName];
if( ![pathOfCurrentFile isEqual: currentDirectory] ) {
currentDirectory = [self popPathStack: directoryStack
untilFoundPath: pathOfCurrentFile];
}
[eventHandler addFile: absoluteFileName
ofParentDirectory: currentDirectory];
[pathOfCurrentFile release];
}
}
[absoluteFileName release];
}
EC_AUTORELEASEPOOL_END
return self;
}
- setObject: (id ) anObject forKey: (id ) aKey
forNode: (id ) aNode {
id dictionaryService;
NSLog( @"KEY=%@", aKey);
dictionaryService = (id )
[aNode serviceWithId: @"FTDictionaryService"];
ECAssertTrue( nil != dictionaryService, @"Unable to get service "\
"FTDictionaryService!" );
[dictionaryService setObject: anObject forKey: aKey ];
[dictionaryService close];
return self;
}
- objectForKey: (id ) aKey forNode: (id ) aNode {
id dictionaryService;
id toReturn = nil;
dictionaryService = (id )
[aNode serviceWithId: @"FTDictionaryService"];
ECAssertTrue( nil != dictionaryService, @"Unable to get service "\
"FTDictionaryService!" );
NSLog( @"KEY=%@", aKey);
toReturn = [dictionaryService objectForKey: aKey ];
[dictionaryService close];
return toReturn;
}
- testFileStore {
id graphManager;
id graph;
id graphId;
id objectToIdMapper;
id transaction;
id graphIdMapper;
NSDictionary *storedNamesToContent;
NSMutableSet *excludeDirs;
NSLog( @"FTFileStoreTEST::testServices: BEGINNING..." );
EC_AUTORELEASEPOOL_BEGIN
objectToIdMapper = [session defaultObjectToIdMapper];
graphManager = [session graphManager];
NSLog( @"Now creating graph..." );
transaction = [session beginTransactionWithParent: nil
withSettings: nil];
graphId = [objectToIdMapper mapObject: @"fileStoreGraph"];
graph = [graphManager createGraphWithId: graphId];
ECAssertTrue( nil != graph, @"Graph creation failed!" );
graphIdMapper = [graph objectToIdMapper];
excludeDirs = [[[NSMutableSet alloc] init] autorelease];
[excludeDirs addObject: @"testdir"];
[self iterateBeginingAtPath:
[[NSFileManager defaultManager] currentDirectoryPath]
//[[[NSProcessInfo processInfo] environment] objectForKey: @"PWD"]
excludeSubDirectories: excludeDirs
sendingEventsTo: [[[FTStoreDirectoryStructure alloc]
initWithGraph: graph
withObjectIdMapper: graphIdMapper] autorelease]];
[transaction commit];
//NSLog( @"FTFileStoreTEST::testServices: Reading all nodes and
transaction = [session beginTransactionWithParent: nil
withSettings: nil];
storedNamesToContent = [self readGraph: graph
withObjectToIdMapper: graphIdMapper];
[self iterateBeginingAtPath:
[[NSFileManager defaultManager] currentDirectoryPath]
//[[[NSProcessInfo processInfo] environment] objectForKey: @"PWD"]
excludeSubDirectories: excludeDirs
sendingEventsTo: [[[FTCompareDirectoryStructure alloc]
initWithNamesToContentMapping: storedNamesToContent] autorelease]];
NSLog( @"FTFileStoreTEST::testServices: Closing FTDictionaryService..." );
[transaction commit];
[graph close];
EC_AUTORELEASEPOOL_END
NSLog( @"FTFileStoreTEST::testServices: FINISHED!" );
return self;
}
- (NSDictionary *) readGraph: (id ) graph
withObjectToIdMapper: (id ) objectToIdMapper {
ECStack *dirNodes;
id currentNode;
id currentId;
NSMutableDictionary *nameToContent;
id dictionaryService;
id outgoingNodes;
EC_AUTORELEASEPOOL_BEGIN
nameToContent = [[NSMutableDictionary alloc] init];
dirNodes = [[[ECStack alloc] init] autorelease];
// read root node and begin iteration with it:
currentId = [objectToIdMapper mapObject: @"ROOTDIR"];
currentNode = [graph nodeWithId: currentId];
NSAssert( nil != currentNode, @"Unable to find node with id=ROOTDIR!" );
[dirNodes pushObject: currentNode];
while( ![dirNodes isEmpty] ) {
NSString *dirName;
currentNode = [dirNodes popObject];
dictionaryService = (id )
[currentNode serviceWithId: @"FTDictionaryService"];
dirName = [dictionaryService objectForKey: @"NAME" ];
[nameToContent setObject: @"DIR" forKey: dirName];
NSLog( @"FTFileStoreTEST::readGraph: Got directory: %@", dirName );
[dictionaryService close];
outgoingNodes = [currentNode outgoingNodes];
while( [outgoingNodes hasNext] ) {
NSString *filename;
NSString *filetype;
currentNode = [outgoingNodes next];
dictionaryService = (id )
[currentNode serviceWithId: @"FTDictionaryService"];
filename = [dictionaryService objectForKey: @"NAME"];
filetype = [dictionaryService objectForKey: @"ContentType"];
if( [filetype isEqual: @"DIR"] ) {
[dirNodes pushObject: currentNode];
} else {
NSData *fileContent;
NSLog( @"FTFileStoreTEST::readGraph: Got file \"%@\" within directory "\
"\"%@\"", filename, dirName );
fileContent = [dictionaryService objectForKey: @"ContentOfFile"];
[nameToContent setObject: [[[NSNumber alloc]
initWithUnsignedInt: [fileContent hash]] autorelease]
forKey: filename];
}
[dictionaryService close];
}
}
EC_AUTORELEASEPOOL_END
return nameToContent;
}
@end
@implementation FTStoreDirectoryStructure
- initWithGraph: (id ) aGraph
withObjectIdMapper: (id ) anObjectToIdMapper {
self = [super init];
self->graph = [aGraph retain];
self->objectToIdMapper = [anObjectToIdMapper retain];
self->directoryToNode = [[NSMutableDictionary alloc] init];
return self;
}
- (void) dealloc {
[self->graph release];
[self->objectToIdMapper release];
[self->directoryToNode release];
[super dealloc];
}
- addDirectory: (NSString *) directory ofParentDirectory: (NSString *) parent {
id nodeId;
id node;
id parentNode;
id dictionaryService;
EC_AUTORELEASEPOOL_BEGIN
NSLog( @"FTStoreDirectoryStructure: Adding directory \"%@\" to parent "\
"directory \"%@\"", directory, parent );
nodeId = [self->objectToIdMapper mapObject: directory];
node = [self->graph createNodeWithId: nodeId];
[self->directoryToNode setObject: node forKey: directory];
if( nil == parent ) {
id rootId = [self->objectToIdMapper
mapObject: @"ROOTDIR"];
parentNode = [self->graph createNodeWithId: rootId];
dictionaryService = (id )
[parentNode serviceWithId: @"FTDictionaryService"];
[dictionaryService setObject: @"DIR" forKey: @"ContentType" ];
[dictionaryService setObject: directory forKey: @"NAME" ];
[dictionaryService close];
} else {
parentNode = [self->directoryToNode objectForKey: parent];
}
if( nil != parentNode ) {
[parentNode createAndAppendEdgeWithId: nodeId withTargetNode: node];
}
dictionaryService = (id )
[node serviceWithId: @"FTDictionaryService"];
[dictionaryService setObject: @"DIR" forKey: @"ContentType" ];
[dictionaryService setObject: directory forKey: @"NAME" ];
[dictionaryService close];
EC_AUTORELEASEPOOL_END
return self;
}
- addFile: (NSString *) aFile ofParentDirectory: (NSString *) parent {
id parentNode;
id fileNode;
id nodeId;
id dictionaryService;
NSData *fileContent;
EC_AUTORELEASEPOOL_BEGIN
NSLog( @"FTStoreDirectoryStructure: Adding file \"%@\" to parent "\
"directory \"%@\"", aFile, parent );
parentNode = [self->directoryToNode objectForKey: parent];
if( nil == parentNode ) {
NSLog( @"FTStoreDirectoryStructure::addFile: Unable to find parent node: "\
"\"%d\"", parentNode );
[NSException raise: @"IllegalStateException"
format: @"Unable to find parent node: \"%d\"", parentNode];
}
nodeId = [self->objectToIdMapper mapObject: aFile];
fileNode = [self->graph createNodeWithId: nodeId];
[parentNode createAndAppendEdgeWithId: nodeId withTargetNode: fileNode];
NSLog( @"FTStoreDirectoryStructure: Now storing content..." );
dictionaryService = (id )
[fileNode serviceWithId: @"FTDictionaryService"];
fileContent = [[[NSData alloc] initWithContentsOfFile: aFile]
autorelease];
[dictionaryService setObject: fileContent forKey: @"ContentOfFile" ];
[dictionaryService setObject: @"FILE" forKey: @"ContentType" ];
[dictionaryService setObject: aFile forKey: @"NAME" ];
[dictionaryService close];
EC_AUTORELEASEPOOL_END
return self;
}
@end
@implementation FTCompareDirectoryStructure
- initWithNamesToContentMapping: (NSDictionary*) someNamesToContent {
self = [super init];
self->namesToContent = [someNamesToContent retain];
return self;
}
- (void) dealloc {
[self->namesToContent release];
[super dealloc];
}
- addDirectory: (NSString *) directory ofParentDirectory: (NSString *) parent {
EC_AUTORELEASEPOOL_BEGIN
if( nil == [self->namesToContent objectForKey: directory] ) {
[NSException raise: @"IllegalStateException"
format: @"Unable to find directory \"%d\" in database.", parent];
}
NSLog( @"FTCompareDirectoryStructure: Got directory \"%@\" of parent "\
"directory \"%@\"", directory, parent );
EC_AUTORELEASEPOOL_END
return self;
}
- addFile: (NSString *) aFile ofParentDirectory: (NSString *) parent {
if( nil == [self->namesToContent objectForKey: aFile] ) {
[NSException raise: @"IllegalStateException"
format: @"Unable to find file \"%d\" in database.", aFile];
}
NSLog( @"FTCompareDirectoryStructure: Found file \"%@\" to parent "\
"directory \"%@\"", aFile, parent );
return self;
}
@end