#include "LCIndexManager.h" #include "LCRAMDirectory.h" #include "LCFSDirectory.h" #include "LCSimpleAnalyzer.h" #include "GNUstep.h" static LCIndexManager *sharedInstance; @implementation LCIndexManager /** Check whether an index is existed at path */ + (BOOL) indexExistsAtPath: (NSString *) path { return [LCIndexReader indexExistsAtPath: path]; } /** Initiate an index data in memory */ - (id) init { LCRAMDirectory *d = AUTORELEASE([[LCRAMDirectory alloc] init]); LCSimpleAnalyzer *a = AUTORELEASE([[LCSimpleAnalyzer alloc] init]); return [self initWithDirectory: d analyzer: a create: YES]; } /** Initiate an index data at path. * (1) If create is YES and path doesn't exist, a new index data (directory) will be created. * (2) If create is NO and paht doesn't exist, it will return nil. * (3) If create is YES and path exists, the path will be removed and new index will be created. * (4) If create is NO, path exists and is indeed an index data, it will used. * (5) If create is NO, path exists and is not an index data, it will return nil; */ - (id) initWithPath: (NSString *) path create: (BOOL) c { /* Check path */ NSFileManager *manager = [NSFileManager defaultManager]; BOOL isDir; if (c == YES) { if ([manager fileExistsAtPath: path isDirectory: &isDir]) { /* (3), remove path */ [manager removeFileAtPath: path handler: nil]; } } else { if ([manager fileExistsAtPath: path isDirectory: &isDir]) { if (isDir && [LCIndexManager indexExistsAtPath: path]) { /* (4) */ } else { return nil; /* (5) */ } } else { /* (2) */ return nil; } } /* (1), (3) */ return [self initWithDirectory: [LCFSDirectory directoryAtPath: path create: c] analyzer: AUTORELEASE([[LCSimpleAnalyzer alloc] init]) create: c]; } /** Use Lucene LCDirectory as virtual file system */ - (id) initWithDirectory: (id ) d create: (BOOL) c { importers = [[NSMutableArray alloc] init]; paths = [[NSMutableArray alloc] init]; pairs = [[NSMutableDictionary alloc] init]; return [self initWithDirectory: d analyzer: AUTORELEASE([[LCSimpleAnalyzer alloc] init]) create: c]; } /** Add path for indexing. * This is not stored in index, therefore, for each new LCIndexManager, * it must be set before use LCIndexManager. * Otherwise, nothing will be indexed. * If path is a directory, it will index everything within this directory and its subdirectory. */ - (void) addIndexPath: (NSString *) path { [paths addObject: path]; } /** Set indexPaths */ - (void) setIndexPaths: (NSArray *) p { [paths setArray: p]; } /** return indexPaths */ - (NSArray *) indexPaths { return paths; } /** Add importer for indexing. * Each file (item) in path will be indexed by each importer. * If two importers use the same file type, * each file will be indexed twice. * It is the responsibility of importer to know which type of file it should handle. */ - (void) addImporter: (id ) importer { [importers addObject: importer]; } - (void) setImporters: (NSArray *) i { [importers setArray: i]; } - (NSArray *) importers { return importers; } /** Specify importers for a given path. * This override the general rules of indexing above. * Only the specified importers will be used for path and its subdirectory (if sub is YES). * If importers is nil, path will not be indexed. */ - (void) setIndexPath: (NSString *) path importers: (NSArray *) i includeSubpaths: (BOOL) sub { /* Internally, appending '+' as prefix for path including subdirectory, and '-' for not requiring */ NSString *new; if (sub) new = [NSString stringWithFormat: @"+%@", path]; else new = [NSString stringWithFormat: @"-%@", path]; [pairs setObject: i forKey: new]; } /** index everything under -indexPaths. * It search all the existed document under -indexPaths, remove them, and add them back. * Warn: it cost a lot. It do search and delete, add index if necessary. */ - (void) indexAllFiles { } /** index new. * It compare the value of updateAttributes to determine whether a file should be indexed. * Warn: it cost a lot. It do search, compare and delete, add, index if necessary. */ - (void) indexUpdatedFiles { } /** Index one file * This should be used most commonly within any application while an file (item) changed. * It is basically a combination of -setIndexPaths: and -indexAll. * Since there is only one file at a time, the cost is less. */ - (void) indexAtPath: (NSString *) path { } /** Index one file with importer */ - (void) indexAtPath: (NSString *) path importer: (id ) importer { } /** Remove the document at path. * It do search, delete. */ - (void) removeMetadataAtPath: (NSString *) path { } /* Search */ /** Return search result based on query. * Return an array of values at keyAttribute. */ - (NSArray *) searchWithString: (NSString *) query { return nil; } /** Return search result based on query. */ - (NSArray *) searchWithQuery: (LCQuery *) query { return nil; } /* Advanced funcation */ /** Return indexReader. * IndexReader and IndexWriter cannot exist at the same time. * When one is called, the other is closed by IndexManager. * Do not close indexReader or indexWriter on you own. * But when you have any of them, do not use the other one because it is closed. */ - (LCIndexReader *) indexReader { return indexReader; } /** Return indexWriter. See -indexReader */ - (LCIndexWriter *) indexWriter { return indexWriter; } /** Return LCDocument at path */ - (LCDocument *) documentAtPath: (NSString *) path { return nil; } /** default analyzer */ - (void) setAnalyzer: (LCAnalyzer *) a { ASSIGN(analyzer, a); } - (LCAnalyzer *) analyzer { return analyzer; } /** LCDirectory */ - (id ) directory { return directory; } @end