/*! @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