diff options
author | Brian Cully <bjc@kublai.com> | 2008-04-14 21:45:08 -0400 |
---|---|---|
committer | Brian Cully <github.20.shmit@spamgourmet.com> | 2008-04-14 21:45:08 -0400 |
commit | 17349a5e426dc7acf1216a3767a22f69974cbca0 (patch) | |
tree | 20029d02f07ab6257cccec36d34fb312f796e1d1 /Frameworks/LiBackend | |
download | liaison-17349a5e426dc7acf1216a3767a22f69974cbca0.tar.gz liaison-17349a5e426dc7acf1216a3767a22f69974cbca0.zip |
Initial commit.
Diffstat (limited to 'Frameworks/LiBackend')
-rw-r--r-- | Frameworks/LiBackend/English.lproj/LiBackend.scriptTerminology | 79 | ||||
-rw-r--r-- | Frameworks/LiBackend/Info.plist | 26 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiBackend.h | 17 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiBackend.scriptSuite | 101 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiFileHandle.h | 103 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiFileHandle.m | 476 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiFileStore.h | 168 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiFileStore.m | 1040 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiFilter.h | 38 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiFilter.m | 108 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiLog.h | 21 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiLog.m | 104 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiPreferences.h | 31 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiPreferences.m | 209 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiStoreValidator.h | 11 | ||||
-rw-r--r-- | Frameworks/LiBackend/LiStoreValidator.m | 13 |
16 files changed, 2545 insertions, 0 deletions
diff --git a/Frameworks/LiBackend/English.lproj/LiBackend.scriptTerminology b/Frameworks/LiBackend/English.lproj/LiBackend.scriptTerminology new file mode 100644 index 0000000..5e586f9 --- /dev/null +++ b/Frameworks/LiBackend/English.lproj/LiBackend.scriptTerminology @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Classes</key> + <dict> + <key>LiFileHandle</key> + <dict> + <key>Attributes</key> + <dict> + <key>dictionary</key> + <dict> + <key>Description</key> + <string>The complete attribute dictionary.</string> + <key>Name</key> + <string>dictionary</string> + </dict> + <key>fileHandle</key> + <dict> + <key>Description</key> + <string>The unique file identifier which locates a file in a library.</string> + <key>Name</key> + <string>id</string> + </dict> + <key>filename</key> + <dict> + <key>Description</key> + <string>The filename of the file, without type extension.</string> + <key>Name</key> + <string>name</string> + </dict> + <key>urlString</key> + <dict> + <key>Description</key> + <string>A URL which locates this file.</string> + <key>Name</key> + <string>address</string> + </dict> + </dict> + <key>Description</key> + <string>A file.</string> + <key>Name</key> + <string>file</string> + <key>PluralName</key> + <string>files</string> + </dict> + <key>LiFileStore</key> + <dict> + <key>Attributes</key> + <dict> + <key>name</key> + <dict> + <key>Description</key> + <string>The name of the library.</string> + <key>Name</key> + <string>name</string> + </dict> + <key>storeID</key> + <dict> + <key>Description</key> + <string>The unique store identifier.</string> + <key>Name</key> + <string>id</string> + </dict> + </dict> + <key>Description</key> + <string>A file library.</string> + <key>Name</key> + <string>library</string> + <key>PluralName</key> + <string>libraries</string> + </dict> + </dict> + <key>Description</key> + <string>Liaison's low-level scripting interface.</string> + <key>Name</key> + <string>LiBackend suite</string> +</dict> +</plist> diff --git a/Frameworks/LiBackend/Info.plist b/Frameworks/LiBackend/Info.plist new file mode 100644 index 0000000..f3c92de --- /dev/null +++ b/Frameworks/LiBackend/Info.plist @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>LiBackend</string> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string>com.kublai.Liaison.LiBackend</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>0.4d</string> + <key>NSAppleScriptEnabled</key> + <string>YES</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Frameworks/LiBackend/LiBackend.h b/Frameworks/LiBackend/LiBackend.h new file mode 100644 index 0000000..3c6465a --- /dev/null +++ b/Frameworks/LiBackend/LiBackend.h @@ -0,0 +1,17 @@ +/* + * LiBackend.h + * Liaison + * + * Created by Brian Cully on Fri May 30 2003. + * Copyright (c) 2003 Brian Cully. All rights reserved. + * + */ + +#import <Cocoa/Cocoa.h> + +#import <LiBackend/LiFileStore.h> +#import <LiBackend/LiFileHandle.h> +#import <LiBackend/LiFilter.h> +#import <LiBackend/LiStoreValidator.h> +#import <LiBackend/LiPreferences.h> +#import <LiBackend/LiLog.h>
\ No newline at end of file diff --git a/Frameworks/LiBackend/LiBackend.scriptSuite b/Frameworks/LiBackend/LiBackend.scriptSuite new file mode 100644 index 0000000..01e0daa --- /dev/null +++ b/Frameworks/LiBackend/LiBackend.scriptSuite @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>AppleEventCode</key> + <string>LiBE</string> + <key>Classes</key> + <dict> + <key>LiFileHandle</key> + <dict> + <key>AppleEventCode</key> + <string>LiFH</string> + <key>Attributes</key> + <dict> + <key>dictionary</key> + <dict> + <key>AppleEventCode</key> + <string>prec</string> + <key>ReadOnly</key> + <string>YES</string> + <key>Type</key> + <string>NSDictionary</string> + </dict> + <key>fileHandle</key> + <dict> + <key>AppleEventCode</key> + <string>ID </string> + <key>ReadOnly</key> + <string>YES</string> + <key>Type</key> + <string>NSNumber<UnsignedLong></string> + </dict> + <key>filename</key> + <dict> + <key>AppleEventCode</key> + <string>pnam</string> + <key>ReadOnly</key> + <string>NO</string> + <key>Type</key> + <string>NSString</string> + </dict> + <key>urlString</key> + <dict> + <key>AppleEventCode</key> + <string>curl</string> + <key>ReadOnly</key> + <string>YES</string> + <key>Type</key> + <string>NSString</string> + </dict> + </dict> + <key>Superclass</key> + <string>NSCoreSuite.AbstractObject</string> + <key>SupportedCommands</key> + <dict/> + </dict> + <key>LiFileStore</key> + <dict> + <key>AppleEventCode</key> + <string>LiFS</string> + <key>Attributes</key> + <dict> + <key>name</key> + <dict> + <key>AppleEventCode</key> + <string>pnam</string> + <key>ReadOnly</key> + <string>NO</string> + <key>Type</key> + <string>NSString</string> + </dict> + <key>storeID</key> + <dict> + <key>AppleEventCode</key> + <string>ID </string> + <key>ReadOnly</key> + <string>YES</string> + <key>Type</key> + <string>NSNumber<UnsignedLong></string> + </dict> + </dict> + <key>Superclass</key> + <string>NSCoreSuite.AbstractObject</string> + <key>ToManyRelationships</key> + <dict> + <key>allFileHandles</key> + <dict> + <key>AppleEventCode</key> + <string>LiFH</string> + <key>ReadOnly</key> + <string>NO</string> + <key>Type</key> + <string>LiFileHandle</string> + </dict> + </dict> + </dict> + </dict> + <key>Name</key> + <string>LiBackend</string> +</dict> +</plist> diff --git a/Frameworks/LiBackend/LiFileHandle.h b/Frameworks/LiBackend/LiFileHandle.h new file mode 100644 index 0000000..5e5dcb3 --- /dev/null +++ b/Frameworks/LiBackend/LiFileHandle.h @@ -0,0 +1,103 @@ +// +// LiFileHandle.h +// Liaison +// +// Created by Brian Cully on Sat May 24 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +@interface LiFileHandle : NSObject <NSCoding> +{ + id theStoreID; + id theFileID; +} ++ (LiFileHandle *)fileHandleWithID: (id)aFileID + storeID: (id)aStoreID; + +// For the file validator methods. +- (BOOL)shouldUpdate; + +- (id)valueForAttribute: (NSString *)anAttribute; +- (void)setValue: (id)aValue forAttribute: (NSString *)anAttribute; +- (NSArray *)valuesForAttributes: (NSArray *)someAttributes; +- (void)setValues: (NSArray *)someValues forAttributes: (NSArray *)someAttributes; +@property (retain,getter=fileID) id theFileID; +@property (retain,getter=storeID) id theStoreID; +@end + +@interface LiFileHandle (Accessors) +- (id)storeID; +- (void)setStoreID: (id)aStoreID; +- (id)fileID; +- (void)setFileID: (id)aFileID; +@end + +// These are common access methods - actually nothing more than convenience +// methods that are nothing more than wrappers to valueForAttribute: and +// setValue:forAttribute: +// It is recommended that plugins use the same method for attribute access. +@interface LiFileHandle (CommonAccessors) +- (LiFileStore *)fileStore; +- (void)setFileStore: (LiFileStore *)aFileStore; +- (BOOL)isEditable; +- (void)setIsEditable: (BOOL)editable; +- (NSString *)filename; +- (void)setFilename: (NSString *)aFilename; +- (NSString *)type; +- (void)setType: (NSString *)aType; +- (NSNumber *)hfsCreator; +- (void)setHFSCreator: (NSNumber *)aTypeCode; +- (NSNumber *)hfsType; +- (void)setHFSType: (NSNumber *)aTypeCode; +- (NSString *)application; +- (void)setApplication: (NSString *)pathToApp; +- (NSDate *)lastModifiedTime; +- (void)setLastModifiedTime: (NSDate *)aTime; +- (NSDate *)creationTime; +- (void)setCreationTime: (NSDate *)aTime; +- (NSNumber *)fileSize; + +- (NSMutableArray *)groups; +- (void)addToGroup: (NSString *)aGroup; +- (BOOL)isMemberOfGroup: (NSString *)aGroup; +- (void)removeFromGroup: (NSString *)aGroup; +- (void)renameGroup: (NSString *)oldName toGroup: (NSString *)newName; +- (BOOL)matchesFilter: (LiFilter *)aFilter; +@end + +@interface LiFileHandle (CommonUtilities) +- (NSString *)description; +- (NSDictionary *)dictionary; +- (void)update; +- (void)open; +- (NSURL *)url; +@end + +@interface LiFileHandle (Scripting) +- (NSScriptObjectSpecifier *)objectSpecifier; + +- (NSString *)urlString; +@end + +@interface LiFileStore (LiFileHandleMethods) +// Add a file to the library with the results of +// [LiFileStore fileSystemAttributesForPath:]. +- (LiFileHandle *)addFileWithAttributes: (NSDictionary *)someAttributes; + +// To get a file's attributes. +- (NSDictionary *)attributesForFileHandle: (LiFileHandle *)aFileHandle; + +// Set the attributes to be updated in the dictionary. +- (void)updateFileHandle: (LiFileHandle *)aFileHandle + withAttributes: (NSDictionary *)someAttributes; + +// Remove file from the library. +- (void)removeFileHandle: (LiFileHandle *)aFileHandle; + +// Returns all the LiFileHandles in the store. +- (NSArray *)allFileHandles; + +// Returns a list of LiFileHandle objects for attributes +// that match the dictionary. +- (NSArray *)filesMatchingFilter: (LiFilter *)aFilter; +@end
\ No newline at end of file diff --git a/Frameworks/LiBackend/LiFileHandle.m b/Frameworks/LiBackend/LiFileHandle.m new file mode 100644 index 0000000..4f057c1 --- /dev/null +++ b/Frameworks/LiBackend/LiFileHandle.m @@ -0,0 +1,476 @@ +// +// LiFileHandle.m +// Liaison +// +// Created by Brian Cully on Sat May 24 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +#import "LiFileHandle.h" + +@implementation LiFileHandle (Copying) +- (id)copyWithZone: (NSZone *)aZone +{ + LiFileHandle *tmpHandle; + + tmpHandle = [[LiFileHandle allocWithZone: aZone] init]; + [tmpHandle setStoreID: [self storeID]]; + [tmpHandle setFileID: [self fileID]]; + + return tmpHandle; +} + +- (unsigned)hash +{ + unsigned long storeID, fileID; + + storeID = [[self storeID] unsignedLongValue]; + fileID = [[self fileID] unsignedLongValue]; + + // Fold the store ID down to 4 bits. + storeID = (storeID & 0xf) ^ (storeID >> 4 & 0xf) ^ + (storeID >> 8 & 0xf) ^ (storeID >> 12 & 0xf) ^ + (storeID >> 16 & 0xf) ^ (storeID >> 20 & 0xf) ^ + (storeID >> 24 & 0xf) ^ (storeID >> 28 & 0xf); + + // Fold the handle to 12 bits. + fileID = (fileID & 0xfff) ^ (fileID >> 12 & 0xfff) ^ + (fileID >> 24 & 0xfff); + + return (storeID << 12) | fileID; +} + +- (BOOL)isEqual: (id)anObject +{ + if ([anObject isKindOfClass: [self class]]) { + IMP compareMethod; + id myID; + + myID = [self fileID]; + compareMethod = [myID methodForSelector: @selector(compare:)]; + if (compareMethod != nil && + compareMethod(myID, @selector(compare:), [anObject fileID]) == 0) { + myID = [self storeID]; + compareMethod = [myID methodForSelector: @selector(compare:)]; + if (compareMethod != nil && + compareMethod(myID, @selector(compare:), [anObject storeID]) == 0) + return YES; + } + } + + return NO; +} +@end + +@implementation LiFileHandle ++ (LiFileHandle *)fileHandleWithID: (id)aFileID + storeID: (id)aStoreID +{ + LiFileHandle *tmpHandle; + + tmpHandle = [[[LiFileHandle alloc] init] autorelease]; + [tmpHandle setFileID: aFileID]; + [tmpHandle setStoreID: aStoreID]; + + return tmpHandle; +} + +- (id)init +{ + return [super init]; +} + +- (void)dealloc +{ + [self setStoreID: nil]; + [self setFileID: nil]; + + [super dealloc]; +} + +- (id)initWithCoder: (NSCoder *)aCoder +{ + id storeID, fileID; + + self = [self init]; + + if ([aCoder allowsKeyedCoding]) { + storeID = [aCoder decodeObjectForKey: @"LiStoreID"]; + fileID = [aCoder decodeObjectForKey: @"LiFileID"]; + } else { + storeID = [aCoder decodeObject]; + fileID = [aCoder decodeObject]; + } + [self setStoreID: storeID]; + [self setFileID: fileID]; + + return self; +} + +- (void)encodeWithCoder: (NSCoder *)aCoder +{ + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject: [self storeID] + forKey: @"LiStoreID"]; + [aCoder encodeObject: [self fileID] + forKey: @"LiFileID"]; + } else { + [aCoder encodeObject: [self storeID]]; + [aCoder encodeObject: [self fileID]]; + } +} + +- (BOOL)shouldUpdate +{ + return NO; +} + +- (id)valueForAttribute: (NSString *)anAttribute +{ + NSDictionary *attrDict; + + attrDict = [self dictionary]; + return [attrDict objectForKey: anAttribute]; +} + +- (void)setValue: (id)aValue forAttribute: (NSString *)anAttribute +{ + if (aValue != nil) + [self setValues: [NSArray arrayWithObject: aValue] + forAttributes: [NSArray arrayWithObject: anAttribute]]; +} + +- (NSArray *)valuesForAttributes: (NSArray *)someAttributes +{ + NSDictionary *attributes; + NSMutableArray *someValues; + NSString *attribute; + + attributes = [self dictionary]; + someValues = [NSMutableArray array]; + for (attribute in someAttributes) { + [someValues addObject: [attributes objectForKey: attribute]]; + } + + return someValues; +} + +- (void)setValues: (NSArray *)someValues forAttributes: (NSArray *)someAttributes +{ + NSDictionary *newAttributes; + + newAttributes = [NSDictionary dictionaryWithObjects: someValues + forKeys: someAttributes]; + [[self fileStore] updateFileHandle: self withAttributes: newAttributes]; +} +@synthesize theStoreID; +@synthesize theFileID; +@end + +@implementation LiFileHandle (Accessors) +- (id)storeID +{ + return theStoreID; +} + +- (void)setStoreID: (id)aStoreID +{ + [aStoreID retain]; + [theStoreID release]; + theStoreID = aStoreID; +} + +- (id)fileID +{ + return theFileID; +} + +- (void)setFileID: (id)aFileID +{ + [aFileID retain]; + [theFileID release]; + theFileID = aFileID; +} +@end + +@implementation LiFileHandle (CommonAccessors) +- (LiFileStore *)fileStore +{ + return [LiFileStore fileStoreWithID: [self storeID]]; +} + +- (void)setFileStore: (LiFileStore *)aFileStore +{ + [self setStoreID: [aFileStore storeID]]; +} + +- (BOOL)isEditable +{ + return [[self valueForAttribute: LiIsEditableAttribute] boolValue]; +} + +- (void)setIsEditable: (BOOL)editable +{ + [self setValue: [NSNumber numberWithBool: editable] + forAttribute: LiIsEditableAttribute]; +} + +- (NSString *)filename +{ + return [self valueForAttribute: LiFilenameAttribute]; +} + +- (void)setFilename: (NSString *)aFilename +{ + [self setValue: aFilename forAttribute: LiFilenameAttribute]; +} + +- (NSString *)type +{ + return [self valueForAttribute: LiTypeAttribute]; +} + +- (void)setType: (NSString *)aType +{ + [self setValue: aType forAttribute: LiTypeAttribute]; +} + +- (NSNumber *)hfsCreator +{ + return [self valueForAttribute: LiHFSCreatorAttribute]; +} + +- (void)setHFSCreator: (NSNumber *)aTypeCode +{ + [self setValue: aTypeCode forAttribute: LiHFSCreatorAttribute]; +} + +- (NSNumber *)hfsType +{ + return [self valueForAttribute: LiHFSTypeAttribute]; +} + +- (void)setHFSType: (NSNumber *)aTypeCode +{ + [self setValue: aTypeCode forAttribute: LiHFSTypeAttribute]; +} + +- (NSString *)application +{ + return [self valueForAttribute: LiApplicationAttribute]; +} + +- (void)setApplication: (NSString *)pathToApp +{ + [self setValue: pathToApp forAttribute: LiApplicationAttribute]; +} + +- (NSDate *)lastModifiedTime +{ + return [self valueForAttribute: LiLastModifiedDateAttribute]; +} + +- (void)setLastModifiedTime: (NSDate *)aTime +{ + [self setValue: aTime forAttribute: LiLastModifiedDateAttribute]; +} + +- (NSDate *)creationTime +{ + return [self valueForAttribute: LiCreationDateAttribute]; +} + +- (void)setCreationTime: (NSDate *)aTime +{ + [self setValue: aTime forAttribute: LiCreationDateAttribute]; +} + +- (NSNumber *)fileSize +{ + return [self valueForAttribute: LiFileSizeAttribute]; +} + +- (NSMutableArray *)groups +{ + return [self valueForAttribute: LiGroupsAttribute]; +} + +- (void)addToGroup: (NSString *)aGroup +{ + NSMutableArray *myGroups, *newGroups; + + myGroups = [self groups]; + if (myGroups != nil) { + if ([myGroups containsObject: aGroup]) { + return; + } + newGroups = [NSMutableArray arrayWithArray: myGroups]; + } else + newGroups = [NSMutableArray array]; + [newGroups addObject: aGroup]; + [self setValue: newGroups forAttribute: LiGroupsAttribute]; +} + +- (BOOL)isMemberOfGroup: (NSString *)aGroup +{ + return [[self groups] containsObject: aGroup]; +} + +- (void)removeFromGroup: (NSString *)aGroup +{ + NSMutableArray *myGroups, *newGroups; + + myGroups = [self groups]; + if (myGroups != nil) { + newGroups = [NSMutableArray arrayWithArray: myGroups]; + [newGroups removeObject: aGroup]; + [self setValue: newGroups forAttribute: LiGroupsAttribute]; + } +} + +- (void)renameGroup: (NSString *)oldName toGroup: (NSString *)newName +{ + NSMutableArray *myGroups, *newGroups; + + myGroups = [self groups]; + if (myGroups != nil) { + newGroups = [NSMutableArray arrayWithArray: myGroups]; + [newGroups removeObject: oldName]; + [newGroups addObject: newName]; + [self setValue: newGroups forAttribute: LiGroupsAttribute]; + } +} + +- (BOOL)matchesFilter: (LiFilter *)aFilter +{ + return [[self fileStore] attributes: [self dictionary] matchFilter: aFilter]; +} +@end + +@implementation LiFileHandle (CommonUtilities) +- (NSString *)description +{ + return [[self dictionary] description]; +} + +- (NSDictionary *)dictionary +{ + return [[self fileStore] attributesForFileID: [self fileID]]; +} + +- (void)update +{ + [[[self fileStore] delegate] updateFileHandle: self]; +} + +- (void)open +{ + [[[self fileStore] delegate] openFileHandle: self]; +} + +- (NSURL *)url +{ + return [[[self fileStore] delegate] urlForFileHandle: self]; +} +@end + +@implementation LiFileHandle (Scripting) +- (NSScriptObjectSpecifier *)objectSpecifier +{ + NSScriptClassDescription *containerDescription; + NSScriptObjectSpecifier *containerRef; + unsigned index; + + [LiLog logAsDebug: @"[LiFileHandle objectSpecifier]"]; + + index = [[[self fileStore] allFileHandles] indexOfObject: self]; + if (index != NSNotFound) { + [LiLog logAsDebug: @"index: %@", [NSNumber numberWithUnsignedInt: index]]; + containerRef = [LiFileStore objectSpecifier]; + containerDescription = (NSScriptClassDescription *)[NSScriptClassDescription classDescriptionForClass:[LiFileStore class]]; + + return [[[NSIndexSpecifier alloc] initWithContainerClassDescription:containerDescription containerSpecifier:containerRef key:@"allFileHandles" index:index] autorelease]; + } else + return nil; +} + +- (NSString *)urlString +{ + return [[self url] absoluteString]; +} +@end + +@implementation LiFileStore (LiFileHandleMethods) +- (LiFileHandle *)addFileWithAttributes: (NSDictionary *)someAttributes +{ + LiFileHandle *tmpHandle; + id fileID; + + tmpHandle = nil; + fileID = [self fileIDWithAttributes: someAttributes]; + if (fileID != nil) + tmpHandle = [LiFileHandle fileHandleWithID: fileID storeID: [self storeID]]; + return tmpHandle; +} + +- (NSDictionary *)attributesForFileHandle: (LiFileHandle *)aFileHandle +{ + return [self attributesForFileID: [aFileHandle fileID]]; +} + +- (void)updateFileHandle: (LiFileHandle *)aFileHandle + withAttributes: (NSDictionary *)someAttributes +{ + [self updateFileID: [aFileHandle fileID] withAttributes: someAttributes]; +} + +- (void)removeFileHandle: (LiFileHandle *)aFileHandle +{ + [self removeFileID: [aFileHandle fileID]]; +} + +- (NSArray *)allFileHandles +{ + NSEnumerator *idEnum; + NSMutableArray *fileHandles; + id fileID; + + fileHandles = [NSMutableArray array]; + idEnum = [[self allFileIDs] objectEnumerator]; + while ((fileID = [idEnum nextObject]) != nil) { + LiFileHandle *tmpHandle; + + tmpHandle = [[LiFileHandle alloc] init]; + [tmpHandle setStoreID: [self storeID]]; + [tmpHandle setFileID: fileID]; + [fileHandles addObject: tmpHandle]; + [tmpHandle release]; + } + + return fileHandles; +} + +- (NSArray *)filesMatchingFilter: (LiFilter *)aFilter +{ + NSArray *fileIDs; + NSMutableArray *fileHandles; + + fileHandles = nil; + fileIDs = [self fileIDsMatchingFilter: aFilter]; + if ([fileIDs count] > 0) { + id fileID; + + fileHandles = [NSMutableArray array]; + for (fileID in fileIDs) { + LiFileHandle *tmpHandle; + + tmpHandle = [[LiFileHandle alloc] init]; + [tmpHandle setStoreID: [self storeID]]; + [tmpHandle setFileID: fileID]; + [fileHandles addObject: tmpHandle]; + [tmpHandle release]; + } + } + return fileHandles; +} +@end
\ No newline at end of file diff --git a/Frameworks/LiBackend/LiFileStore.h b/Frameworks/LiBackend/LiFileStore.h new file mode 100644 index 0000000..cba804c --- /dev/null +++ b/Frameworks/LiBackend/LiFileStore.h @@ -0,0 +1,168 @@ +// +// LiFileStore.h +// Liaison +// +// Created by Brian Cully on Sat May 24 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +// Notification names. +// +// When the file store list changes. +#define LiFileStoresChangedNotification @"LiFileStoresChangedNotification" +// When a file gets changed. +#define LiFileChangedNotification @"LiFileChangedNotification" + +// Keys in the userInfo for LiFileStoresChangedNotification +#define LiFileStoreAdded @"LiFileStoreAdded" +#define LiFileStoreRemoved @"LiFileStoreRemoved" + +// Keys in the userInfo for LiFileChangedNotification. +#define LiFilesAdded @"LiFilesAdded" +#define LiFilesChanged @"LiFilesChanged" +#define LiFilesRemoved @"LiFilesRemoved" + +// For LiFilesChanged and LiFilesRemoved. +#define LiFileOldAttributes @"LiFilesOldAttributes" + +// The keys we supply for every file. +#define LiFileHandleAttribute @"LiFileHandleAttribute" +#define LiDirectoryAttribute @"LiDirectoryAttribute" +#define LiFilenameAttribute @"LiFilenameAttribute" +#define LiTypeAttribute @"LiTypeAttribute" +#define LiLastModifiedDateAttribute @"LiLastModifiedDateAttribute" +#define LiCreationDateAttribute @"LiCreationDateAttribute" +#define LiFileSizeAttribute @"LiFileSizeAttribute" +#define LiGroupsAttribute @"LiGroupsAttribute" +#define LiHFSCreatorAttribute @"LiHFSCreatorAttribute" +#define LiHFSTypeAttribute @"LiHFSTypeAttribute" +#define LiApplicationAttribute @"LiApplicationAttribute" +#define LiIsEditableAttribute @"LiIsEditableAttribute" + +@class LiFileHandle; +@class LiFileStore; +@class LiFilter; + +@protocol LiFileStoreDelegate <NSObject> +// Sync the file store database to permanent storage. +- (BOOL)synchronizeFileStore; + + // Sync the file handle to disk. +- (void)synchronizeFileHandle: (LiFileHandle *)aFileHandle + withNewAttributes: (NSMutableDictionary *)someAttributes; + + // Update a file handle from permanent storage. +- (BOOL)shouldUpdateFileHandle: (LiFileHandle *)aFileHandle; +- (void)updateFileHandle: (LiFileHandle *)aFileHandle; + +// Open a file handle. Since a file must be on local storage to +// open it, if the file doesn't exist there, delegates must first +// create the file before opening it. +- (void)openFileHandle: (LiFileHandle *)aFileHandle; + +// Attempt to add a file, specified by a URL, to the library. +// Returns a non-nil LiFileHandle that matches the newly added file +// on success, nil on failure. +- (LiFileHandle *)addURL: (NSURL *)anURL + toFileStore: (LiFileStore *)aFileStore; + +// Return a standard URL for a file. This can be anything you want, +// but it should always point to the file in some way. +- (NSURL *)urlForFileHandle: (LiFileHandle *)aFileHandle; + +// Used to fill in default values for a particular attribute. +// For instance, you can return a set of groups for LiGroupsAttribute. +- (NSArray *)defaultValuesForAttribute: (NSString *)anAttribute; + +// For messing with the default attributes for a plugin. +- (BOOL)addDefaultAttribute: (NSDictionary *)anAttribute toFileStore: (LiFileStore *)aFileStore; +- (BOOL)changeDefaultValueForAttribute: (NSDictionary *)anAttribute toValue: (id)aValue inFileStore: (LiFileStore *)aFileStore; +- (BOOL)removeDefaultAttribute: (NSDictionary *)anAttribute fromFileStore: (LiFileStore *)aFileStore; +@end + +@interface LiFileStore : NSObject <NSCopying, NSCoding> +{ + id theStoreID; + id <LiFileStoreDelegate>theDelegate; + + BOOL theStoreIsEditable; + + NSImage *theIcon; + NSString *theName; + + NSMutableDictionary *theFiles; + NSMutableDictionary *theIndexes; + + NSMutableSet *theAddedFiles, *theChangedFiles, *theRemovedFiles; + + unsigned long nextHandle; +} +// Look up stores via ID. ++ (NSArray *)allFileStores; ++ (NSEnumerator *)fileStoreEnumerator; ++ (LiFileStore *)fileStoreWithID: (id)aStoreID; ++ (void)removeStoreWithID: (id)aStoreID; + +// Create an auto-released file store. ++ (LiFileStore *)fileStoreWithName: (NSString *)aName; +- (LiFileStore *)initWithName: (NSString *)aName; + +// Use the following methods to control how to manage store indexes. +- (void)addIndexForAttribute: (NSString *)anAttribute; +- (NSMutableDictionary *)indexForAttribute: (NSString *)anAttribute; +- (void)removeIndexForAttribute: (NSString *)anAttribute; + +- (id)fileIDWithAttributes: (NSDictionary *)someAttributes; +- (void)updateFileID: (id)aFileID + withAttributes: (NSDictionary *)someAttributes; +- (void)removeFileID: (id)aFileID; + +- (NSDictionary *)attributesForFileID: (id)aFileID; + +- (NSArray *)allFileIDs; + +- (NSArray *)fileIDsMatchingFilter: (LiFilter *)aFilter; + +// Test attribute dictionaries against a filter. +- (BOOL)attributes: (NSDictionary *)someAttributes + matchFilter: (LiFilter *)aFilter; + +// Return all the values in the library for an attribute. +- (NSArray *)allValuesForAttribute: (NSString *)anAttribute; +@property unsigned long nextHandle; +@property (retain,getter=name) NSString *theName; +@property (retain,getter=icon) NSImage *theIcon; +@property (retain) NSMutableDictionary *theIndexes; +@property (retain,getter=storeID) id theStoreID; +@property (retain,getter=delegate) id <LiFileStoreDelegate>theDelegate; +@property (getter=isEditable,setter=setEditable:) BOOL theStoreIsEditable; +@property (retain) NSMutableDictionary *theFiles; +@end + +@interface LiFileStore (CommonAccessors) +- (void)synchronize; +- (LiFileHandle *)addURL: (NSURL *)anURL; +@end + +@interface LiFileStore (Accessors) +- (id)storeID; +- (void)setStoreID: (id)anID; +- (id <LiFileStoreDelegate>)delegate; +- (void)setDelegate: (id <LiFileStoreDelegate>)aDelegate; +- (BOOL)isEditable; +- (void)setEditable: (BOOL)editable; +- (NSString *)name; +- (void)setName: (NSString *)aName; +- (NSImage *)icon; +- (void)setIcon: (NSImage *)anIcon; +- (NSMutableSet *)addedFiles; +- (void)setAddedFiles: (NSMutableSet *)aSet; +- (NSMutableSet *)changedFiles; +- (void)setChangedFiles: (NSMutableSet *)aSet; +- (NSMutableSet *)removedFiles; +- (void)setRemovedFiles: (NSMutableSet *)aSet; +@end + +@interface LiFileStore (Scripting) +- (NSScriptObjectSpecifier *)objectSpecifier; +@end
\ No newline at end of file diff --git a/Frameworks/LiBackend/LiFileStore.m b/Frameworks/LiBackend/LiFileStore.m new file mode 100644 index 0000000..25c801f --- /dev/null +++ b/Frameworks/LiBackend/LiFileStore.m @@ -0,0 +1,1040 @@ +// +// LiFileStore.m +// Liaison +// +// Created by Brian Cully on Sat May 24 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +#import "LiFileStore.h" + +@interface LiFileStore (Private) +- (unsigned)sendNotifications; +- (void)sendAddNotificationForFileHandle: (LiFileHandle *)aFileHandle; +- (void)sendUpdateNotificationForFileHandle: (LiFileHandle *)aFileHandle + oldAttributes: (NSDictionary *)oldAttrs; +- (void)sendRemoveNotificationForFileHandle: (LiFileHandle *)aFileHandle + oldAttributes: (NSDictionary *)oldAttrs; +@end + +@implementation LiFileStore +static NSMutableDictionary *theFileStores = nil; +static unsigned int theNextID = 0; ++ (NSMutableDictionary *)fileStores +{ + if (theFileStores == nil) + theFileStores = [[NSMutableDictionary alloc] init]; + return theFileStores; +} + ++ (NSArray *)allFileStores +{ + return [[self fileStores] allValues]; +} + ++ (NSEnumerator *)fileStoreEnumerator +{ + return [[self fileStores] objectEnumerator]; +} + ++ (LiFileStore *)fileStoreWithID: (id)aStoreID +{ + return [[self fileStores] objectForKey: aStoreID]; +} + ++ (void)addStore: (LiFileStore *)aFileStore +{ + NSDictionary *userInfo; + NSNotificationCenter *defaultCenter; + + while (([self fileStoreWithID: + [NSNumber numberWithUnsignedInt: theNextID]]) != nil) + theNextID++; + + [[self fileStores] setObject: aFileStore forKey: + [NSNumber numberWithUnsignedInt: theNextID]]; + [aFileStore setStoreID: [NSNumber numberWithUnsignedInt: theNextID]]; + theNextID++; + + userInfo = [NSDictionary dictionaryWithObject: [aFileStore storeID] + forKey: LiFileStoreAdded]; + defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName: LiFileStoresChangedNotification + object: nil + userInfo: userInfo]; +} + ++ (void)removeStoreWithID: (id)aStoreID +{ + NSDictionary *userInfo; + NSNotificationCenter *defaultCenter; + + [[self fileStores] removeObjectForKey: aStoreID]; + + userInfo = [NSDictionary dictionaryWithObject: aStoreID + forKey: LiFileStoreRemoved]; + defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName: LiFileStoresChangedNotification + object: nil + userInfo: userInfo]; +} + ++ (LiFileStore *)fileStoreWithName: (NSString *)aName +{ + return [[[self alloc] initWithName: aName] autorelease]; +} + ++ (NSImage *)defaultIcon +{ + return nil; +} + +- (LiFileStore *)initWithName: (NSString *)aName +{ + self = [super init]; + + [self setName: aName]; + [self setIcon: [[self class] defaultIcon]]; + nextHandle = 1; + theFiles = [[NSMutableDictionary alloc] init]; + + [LiFileStore addStore: self]; + + return self; +} + +- (id)init +{ + NSException *myException; + + [self autorelease]; + + myException = [NSException exceptionWithName: @"LiFileStoreInitFailure" + reason: @"[[LiFileStore alloc] init] isn't supported." + userInfo: nil]; + [myException raise]; + return nil; +} + +- (void)dealloc +{ + [LiFileStore removeStoreWithID: [self storeID]]; + [theFiles release]; + [theIndexes release]; + + [super dealloc]; +} + +- (id)copyWithZone: (NSZone *)aZone +{ + LiFileStore *tmpStore; + + [LiLog logAsDebug: @"[LiFileStore copyWithZone: %@]", aZone]; + + tmpStore = [[LiFileStore allocWithZone: aZone] initWithName: [self name]]; + [tmpStore setEditable: [self isEditable]]; + [tmpStore setIcon: [self icon]]; + + // XXX + tmpStore->theFiles = theFiles; + tmpStore->theIndexes = theIndexes; + tmpStore->nextHandle = nextHandle; + + return tmpStore; +} + +- (id)initWithCoder: (NSCoder *)aCoder +{ + [LiLog logAsDebug: @"[LiFileStore initWithCoder: aCoder]"]; + + self = [self init]; + if (self != nil) { + NSData *iconData; + NSDictionary *fileDB, *indexes; + NSNumber *isEditable, *myNextHandle; + NSString *name; + + if ([aCoder allowsKeyedCoding]) { + name = [aCoder decodeObjectForKey: @"LiFSName"]; + iconData = [aCoder decodeObjectForKey: @"LiFSIconData"]; + isEditable = [aCoder decodeObjectForKey: @"LiFSIsEditable"]; + myNextHandle = [aCoder decodeObjectForKey: @"LiFSNextHandle"]; + fileDB = [aCoder decodeObjectForKey: @"LiFSFileDictionary"]; + indexes = [aCoder decodeObjectForKey: @"LiFSIndexes"]; + } else { + name = [aCoder decodeObject]; + iconData = [aCoder decodeObject]; + isEditable = [aCoder decodeObject]; + myNextHandle = [aCoder decodeObject]; + fileDB = [aCoder decodeObject]; + indexes = [aCoder decodeObject]; + } + [self setName: name]; + [self setIcon: [[[NSImage alloc] initWithData: iconData] autorelease]]; + [self setEditable: [isEditable boolValue]]; + nextHandle = [myNextHandle unsignedLongValue]; + theFiles = [[NSMutableDictionary alloc] initWithDictionary: fileDB]; + theIndexes = [[NSMutableDictionary alloc] initWithDictionary: indexes]; + } + + return self; +} + +- (void)encodeWithCoder: (NSCoder *)aCoder +{ + [LiLog logAsDebug: @"[LiFileStore encodeWithCoder: aCoder]"]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject: [self name] + forKey: @"LiFSName"]; + [aCoder encodeObject: [[self icon] TIFFRepresentation] + forKey: @"LiFSIconData"]; + [aCoder encodeObject: [NSNumber numberWithBool: [self isEditable]] + forKey: @"LiFSIsEditable"]; + [aCoder encodeObject: [NSNumber numberWithUnsignedLong: nextHandle] + forKey: @"LiFSNextHandle"]; + [aCoder encodeObject: theFiles + forKey: @"LiFSFileDictionary"]; + [aCoder encodeObject: theIndexes + forKey: @"LiFSIndexes"]; + } else { + [aCoder encodeObject: [self name]]; + [aCoder encodeObject: [[self icon] TIFFRepresentation]]; + [aCoder encodeObject: [NSNumber numberWithBool: [self isEditable]]]; + [aCoder encodeObject: [NSNumber numberWithUnsignedLong: nextHandle]]; + [aCoder encodeObject: theFiles]; + [aCoder encodeObject: theIndexes]; + } +} + +- (void)addIndexForAttribute: (NSString *)anAttribute +{ + NSEnumerator *fileEnum; + NSMutableDictionary *newIndex; + id fileHandle; + + if ([self indexForAttribute: anAttribute] == nil) { + NSMutableArray *filesInValue; + + [LiLog logAsDebug: @"Indexing %@.", anAttribute]; + + filesInValue = [NSMutableArray array]; + newIndex = [NSMutableDictionary dictionary]; + fileEnum = [theFiles keyEnumerator]; + while ((fileHandle = [fileEnum nextObject]) != nil) { + id value; + + value = [[theFiles objectForKey: fileHandle] objectForKey: anAttribute]; + if (value != nil) { + if ([value isKindOfClass: [NSArray class]]) { + NSEnumerator *valEnum; + id subValue; + + valEnum = [value objectEnumerator]; + while ((subValue = [valEnum nextObject]) != nil) { + filesInValue = [newIndex objectForKey: subValue]; + if (filesInValue == nil) { + filesInValue = [NSMutableArray array]; + [newIndex setObject: filesInValue forKey: subValue]; + } + [filesInValue addObject: fileHandle]; + } + } else { + filesInValue = [newIndex objectForKey: value]; + if (filesInValue == nil) { + filesInValue = [NSMutableArray array]; + [newIndex setObject: filesInValue forKey: value]; + } + [filesInValue addObject: fileHandle]; + } + } + } + + if (theIndexes == nil) + theIndexes = [[NSMutableDictionary alloc] init]; + [theIndexes setObject: newIndex forKey: anAttribute]; + + [LiLog logAsDebug: @"Done indexing %@.", anAttribute]; + } +} + +- (NSMutableDictionary *)indexForAttribute: (NSString *)anAttribute +{ + return [theIndexes objectForKey: anAttribute]; +} + +- (void)removeIndexForAttribute: (NSString *)anAttribute +{ + if ([theIndexes objectForKey: anAttribute] != nil) + [theIndexes removeObjectForKey: anAttribute]; +} + +- (id)fileIDWithAttributes: (NSDictionary *)someAttributes +{ + NSEnumerator *attrEnum; + NSString *attribute; + NSMutableDictionary *fileAttributes; + NSNumber *handle; + + handle = [someAttributes objectForKey: LiFileHandleAttribute]; + if (handle == nil) { + handle = [NSNumber numberWithUnsignedLong: nextHandle]; + nextHandle++; + } else if ([theFiles objectForKey: handle] != nil) { + return handle; + } else + if (nextHandle <= [handle unsignedLongValue]) + nextHandle = [handle unsignedLongValue]+1; + + // First, create the file. + fileAttributes = [NSMutableDictionary dictionaryWithDictionary: someAttributes]; + [fileAttributes setObject: handle forKey: LiFileHandleAttribute]; + [theFiles setObject: fileAttributes forKey: handle]; + + // Then update indexes. + attrEnum = [someAttributes keyEnumerator]; + while ((attribute = [attrEnum nextObject]) != nil) { + NSMutableDictionary *index; + + index = [self indexForAttribute: attribute]; + if (index != nil) { + id myValue; + + myValue = [someAttributes objectForKey: attribute]; + if (myValue != nil) { + NSMutableArray *fileArray; + + if ([myValue isKindOfClass: [NSArray class]]) { + NSEnumerator *valEnum; + id subValue; + + valEnum = [myValue objectEnumerator]; + while ((subValue = [valEnum nextObject]) != nil) { + fileArray = [index objectForKey: subValue]; + if (fileArray == nil) { + fileArray = [NSMutableArray array]; + [index setObject: fileArray forKey: subValue]; + } + [fileArray addObject: handle]; + } + } else { + fileArray = [index objectForKey: myValue]; + if (fileArray == nil) { + fileArray = [NSMutableArray array]; + [index setObject: fileArray forKey: myValue]; + } + [fileArray addObject: handle]; + } + } + } + } + + if (handle != nil) + [self sendAddNotificationForFileHandle: [LiFileHandle fileHandleWithID: handle storeID: [self storeID]]]; + return handle; +} + +- (void)updateFileID: (id)aFileID + withAttributes: (NSDictionary *)someAttributes +{ + NSString *attribute; + NSEnumerator *attrEnum; + NSMutableDictionary *oldAttributes, *newAttributes, *tmpAttributes; + + // Call the delegate's sync method with the new attributes. + // Allow the delegate to filter out attributes it can't modify + // or modify attributes if it has to. + // It should return a dict of what was modified. + newAttributes = [NSMutableDictionary dictionaryWithDictionary: + someAttributes]; + [[self delegate] synchronizeFileHandle: [LiFileHandle fileHandleWithID: aFileID + storeID: [self storeID]] + withNewAttributes: newAttributes]; + + oldAttributes = [theFiles objectForKey: aFileID]; + tmpAttributes = [NSMutableDictionary dictionary]; + attrEnum = [newAttributes keyEnumerator]; + while ((attribute = [attrEnum nextObject]) != nil) { + NSMutableDictionary *index; + id oldValue, newValue; + + oldValue = [oldAttributes objectForKey: attribute]; + newValue = [newAttributes objectForKey: attribute]; + + // For notification. + if (oldValue != nil) + [tmpAttributes setObject: oldValue forKey: attribute]; + + index = [self indexForAttribute: attribute]; + if (index != nil) { + NSMutableArray *fileArray; + + // Remove old values from index. + if (oldValue != nil) { + if ([oldValue isKindOfClass: [NSArray class]]) { + NSEnumerator *valEnum; + id subValue; + + valEnum = [oldValue objectEnumerator]; + while ((subValue = [valEnum nextObject]) != nil) { + fileArray = [index objectForKey: subValue]; + [fileArray removeObject: aFileID]; + if ([fileArray count] == 0) { + [index removeObjectForKey: subValue]; + } + } + } else { + fileArray = [index objectForKey: oldValue]; + [fileArray removeObject: aFileID]; + if ([fileArray count] == 0) { + [index removeObjectForKey: oldValue]; + } + } + } + + // Add new values to index. + if ([newValue isKindOfClass: [NSArray class]]) { + NSEnumerator *valEnum; + id subValue; + + valEnum = [newValue objectEnumerator]; + while ((subValue = [valEnum nextObject]) != nil) { + fileArray = [index objectForKey: subValue]; + if (fileArray == nil) { + fileArray = [NSMutableArray array]; + [index setObject: fileArray forKey: subValue]; + } + [fileArray addObject: aFileID]; + } + } else { + fileArray = [index objectForKey: newValue]; + if (fileArray == nil) { + fileArray = [NSMutableArray array]; + [index setObject: fileArray forKey: newValue]; + } + [fileArray addObject: aFileID]; + } + } + + if (newValue == nil) { + [oldAttributes removeObjectForKey: attribute]; + } else + [oldAttributes setObject: newValue forKey: attribute]; + } + + // Send notification of update if there's something to say. + if ([newAttributes count] > 0) { + [self sendUpdateNotificationForFileHandle: [LiFileHandle fileHandleWithID: aFileID storeID: [self storeID]] + oldAttributes: tmpAttributes]; + } +} + +- (void)removeFileID: (id)aFileID +{ + NSDictionary *fileAttrs; + + fileAttrs = [theFiles objectForKey: aFileID]; + if (fileAttrs != nil) { + NSEnumerator *attrEnum; + NSString *attribute; + + attrEnum = [fileAttrs keyEnumerator]; + while ((attribute = [attrEnum nextObject]) != nil) { + NSMutableDictionary *index; + id myValue; + + myValue = [fileAttrs objectForKey: attribute]; + index = [self indexForAttribute: attribute]; + if (index != nil) { + NSMutableArray *fileArray; + + if ([myValue isKindOfClass: [NSArray class]]) { + NSEnumerator *valEnum; + id subValue; + + valEnum = [myValue objectEnumerator]; + while ((subValue = [valEnum nextObject]) != nil) { + fileArray = [index objectForKey: subValue]; + [fileArray removeObject: aFileID]; + if ([fileArray count] == 0) + [index removeObjectForKey: subValue]; + } + } else { + fileArray = [index objectForKey: myValue]; + [fileArray removeObject: aFileID]; + if ([fileArray count] == 0) + [index removeObjectForKey: myValue]; + } + } + } + + [fileAttrs retain]; + [theFiles removeObjectForKey: aFileID]; + + // Send notification of removal. + if ([fileAttrs count] > 0) { + [self sendRemoveNotificationForFileHandle: [LiFileHandle fileHandleWithID: aFileID storeID: [self storeID]] + oldAttributes: fileAttrs]; + } + [fileAttrs release]; + } +} + +- (NSDictionary *)attributesForFileID: (id)aFileID +{ + return [theFiles objectForKey: aFileID]; +} + +- (NSArray *)allFileIDs +{ + return [theFiles allKeys]; +} + +- (NSDictionary *)fileIDsMatchingFilter: (LiFilter *)aFilter + inList: (NSDictionary *)someFiles +{ + if (aFilter != nil) { + NSDictionary *index; + NSMutableDictionary *matchingFiles; + + matchingFiles = nil; + index = [self indexForAttribute: [aFilter attribute]]; + if (index != nil && [someFiles count] > [index count]) { + NSEnumerator *valEnum; + id value; + + valEnum = [index keyEnumerator]; + while ((value = [valEnum nextObject]) != nil) { + if ([value performSelector: [aFilter compareSelector] + withObject: [aFilter value]]) { + NSEnumerator *idEnum; + id fileID; + + if (matchingFiles == nil) + matchingFiles = [NSMutableDictionary dictionary]; + + idEnum = [[index objectForKey: value] objectEnumerator]; + while ((fileID = [idEnum nextObject]) != nil) { + [matchingFiles setObject: [self attributesForFileID: fileID] + forKey: fileID]; + } + } + } + } else { // Non-indexed + NSEnumerator *idEnum; + id fileID; + + // Go through all the files in the list. + idEnum = [someFiles keyEnumerator]; + while ((fileID = [idEnum nextObject]) != nil) { + if ([self attributes: [someFiles objectForKey: fileID] + matchFilter: aFilter]) { + if (matchingFiles == nil) + matchingFiles = [NSMutableDictionary dictionary]; + [matchingFiles setObject: [self attributesForFileID: fileID] + forKey: fileID]; + } + } + } + return matchingFiles; + } else + return someFiles; +} + +- (NSArray *)fileIDsMatchingFilter: (LiFilter *)aFilter +{ + NSArray *matchingFiles; + if (aFilter != nil) { + matchingFiles = [[self fileIDsMatchingFilter: aFilter inList: theFiles] allKeys]; + } else + matchingFiles = [self allFileIDs]; + + return matchingFiles; +} + +- (BOOL)attributes: (NSDictionary *)someAttributes + matchFilter: (LiFilter *)aFilter +{ + if (aFilter == nil) + return YES; + else if (someAttributes != nil) { + id myValue; + + myValue = [someAttributes objectForKey: [aFilter attribute]]; + if ([myValue respondsToSelector: @selector(objectEnumerator)]) { + NSEnumerator *valueEnum; + id subValue; + + valueEnum = [myValue performSelector: @selector(objectEnumerator)]; + while ((subValue = [valueEnum nextObject]) != nil) { + if ([subValue respondsToSelector: [aFilter compareSelector]]) { + if ([subValue performSelector: [aFilter compareSelector] + withObject: [aFilter value]]) { + return YES; + } + } + } + return NO; + } else { // Non-enumerable + BOOL match; + + match = NO; + if ([myValue respondsToSelector: [aFilter compareSelector]]) + if ([myValue performSelector: [aFilter compareSelector] + withObject: [aFilter value]]) + match = YES; + return match; + } + } else + return NO; +} + +#if 0 +- (BOOL)attributes: (NSDictionary *)someAttributes + match: (NSDictionary *)matchAttributes +{ + BOOL matches; + + matches = YES; + if (someAttributes != nil && [someAttributes count] > 0) { + NSEnumerator *attrEnum; + NSString *attribute; + + attrEnum = [someAttributes keyEnumerator]; + while ((attribute = [attrEnum nextObject]) != nil) { + id myValue, matchValue; + + matchValue = [someAttributes objectForKey: attribute]; + myValue = [someAttributes objectForKey: attribute]; + if (matchValue != myValue) { + if ([myValue isKindOfClass: [NSArray class]]) { + NSEnumerator *valEnum; + id subValue; + + valEnum = [myValue objectEnumerator]; + while ((subValue = [valEnum nextObject]) != nil) { + if (subValue != matchValue) { + if ([subValue respondsToSelector: + @selector(compare:)]) { + if ([subValue performSelector: @selector(compare:) + withObject: matchValue] != 0) + matches = NO; + } else + matches = NO; + } + } + } else if ([myValue respondsToSelector: + @selector(compare:)]) { + if ([myValue performSelector: @selector(compare:) + withObject: matchValue] != 0) + matches = NO; + } else + matches = NO; + } + } + } + + return matches; +} + +- (NSMutableSet *)filesInSet: (NSMutableSet *)fileSet + matchingAttributes: (NSMutableDictionary *)someAttributes +{ + NSEnumerator *attributeEnum; + NSString *attribute, *bestAttribute; + id attributeValue; + long bestCount; + + if (someAttributes == nil || [someAttributes count] == 0) + return fileSet; + + // Find the smallest sets of potential matchers. This allows us to look + // up as few files as possible. + bestAttribute = nil; + bestCount = -1; + attributeEnum = [someAttributes keyEnumerator]; + while ((attribute = [attributeEnum nextObject]) != nil) { + if (bestAttribute == nil) + bestAttribute = attribute; + else { + NSDictionary *index; + + index = [self indexForAttribute: attribute]; + if (index != nil) { + unsigned long indexCount; + + indexCount = [index count]; + if (bestCount == -1) { + bestAttribute = attribute; + bestCount = indexCount; + } else if (bestCount > 1 && bestCount > (long)indexCount) { + bestAttribute = attribute; + bestCount = indexCount; + } + } + } + } + attribute = bestAttribute; + attributeValue = [someAttributes objectForKey: bestAttribute]; + + if (fileSet == nil) { + NSDictionary *index; + + index = [self indexForAttribute: attribute]; + if (index != nil) { + fileSet = [NSMutableSet setWithArray: [index objectForKey: attributeValue]]; + } else { + NSEnumerator *handleEnum; + id handle; + + // Go through every file in the library one by one. Shitty! + fileSet = [NSMutableSet set]; + handleEnum = [theFiles keyEnumerator]; + while ((handle = [handleEnum nextObject]) != nil) { + NSDictionary *handleAttrs; + id myValue; + + handleAttrs = [theFiles objectForKey: handle]; + myValue = [handleAttrs objectForKey: attribute]; + if (myValue != attributeValue) { + if ([myValue isKindOfClass: [NSArray class]]) { + NSEnumerator *valueEnum; + id subValue; + + valueEnum = [myValue objectEnumerator]; + while ((subValue = [valueEnum nextObject]) != nil) { + if (subValue == attributeValue) + [fileSet addObject: handle]; + else if ([subValue respondsToSelector: @selector(compare:)]) { + if ([subValue performSelector: @selector(compare:) + withObject: attributeValue] == 0) { + [fileSet addObject: handle]; + break; + } + } + } + } else if ([myValue respondsToSelector: @selector(compare:)]) + if ([myValue performSelector: @selector(compare:) + withObject: attributeValue] == 0) + [fileSet addObject: handle]; + } else + [fileSet addObject: handle]; + } + } + } else { + NSDictionary *index; + + index = [self indexForAttribute: attribute]; + if (index != nil) { + [fileSet intersectSet: [NSMutableSet setWithArray: [index objectForKey: attributeValue]]]; + } else { + NSEnumerator *handleEnum; + id handle; + + // Go through every file in the set. + handleEnum = [fileSet objectEnumerator]; + while ((handle = [handleEnum nextObject]) != nil) { + NSDictionary *handleAttrs; + id myValue; + + handleAttrs = [theFiles objectForKey: handle]; + myValue = [handleAttrs objectForKey: attribute]; + if (myValue == attributeValue) { + [fileSet removeObject: handle]; + } else if ([myValue respondsToSelector: @selector(compare:)]) { + if ([myValue performSelector: @selector(compare:) + withObject: attributeValue] == 0) + [fileSet removeObject: handle]; + } + } + } + } + + [someAttributes removeObjectForKey: bestAttribute]; + return [self filesInSet: fileSet matchingAttributes: someAttributes]; +} + +- (NSArray *)filesMatchingAttributes: (NSDictionary *)someAttributes +{ + if (someAttributes != nil && [someAttributes count] > 0) { + NSEnumerator *handleEnum; + NSMutableArray *matchingFiles; + id handle; + + matchingFiles = [NSMutableArray array]; + handleEnum = [[self filesInSet: nil + matchingAttributes: [NSMutableDictionary dictionaryWithDictionary: someAttributes]] objectEnumerator]; + while ((handle = [handleEnum nextObject]) != nil) { + LiFileHandle *fileHandle; + + fileHandle = [[LiFileHandle alloc] init]; + [fileHandle setFileStore: self]; + [fileHandle setFileHandle: handle]; + + [matchingFiles addObject: fileHandle]; + [fileHandle release]; + } + return matchingFiles; + } else + return [self allFileHandles]; +} +#endif + +- (NSArray *)allValuesForAttribute: (NSString *)anAttribute +{ + NSArray *valueArray; + NSMutableDictionary *index; + NSMutableSet *values; + + values = [NSMutableSet setWithArray: [[self delegate] defaultValuesForAttribute: anAttribute]]; + index = [self indexForAttribute: anAttribute]; + if (index != nil) { + // Use the index to find the possible values. + [values addObjectsFromArray: [index allKeys]]; + } else { + NSDictionary *fileAttrs; + NSEnumerator *fileEnum; + + // No index. Crappy. Go through every file in the library. + fileEnum = [theFiles objectEnumerator]; + while ((fileAttrs = [fileEnum nextObject]) != nil) { + id value; + + value = [fileAttrs objectForKey: anAttribute]; + if (value != nil && [values member: anAttribute] != nil) { + [values addObject: anAttribute]; + } + } + } + + valueArray = [values allObjects]; + return valueArray; +} +@synthesize theIcon; +@synthesize theDelegate; +@synthesize theFiles; +@synthesize nextHandle; +@synthesize theStoreID; +@synthesize theName; +@synthesize theIndexes; +@end + +@implementation LiFileStore (CommonAccessors) +- (void)synchronize +{ + if ([self sendNotifications] > 0) { + [[self delegate] synchronizeFileStore]; + } +} + +- (LiFileHandle *)addURL: (NSURL *)anURL +{ + return [[self delegate] addURL: anURL toFileStore: self]; +} +@end + +@implementation LiFileStore (Accessors) +- (id)storeID +{ + return theStoreID; +} + +- (void)setStoreID: (id)anID +{ + [anID retain]; + [theStoreID release]; + theStoreID = anID; +} + +- (id <LiFileStoreDelegate>)delegate +{ + return theDelegate; +} + +- (void)setDelegate: (id <LiFileStoreDelegate>)aDelegate +{ + [aDelegate retain]; + [theDelegate release]; + theDelegate = aDelegate; +} + +- (BOOL)isEditable +{ + return theStoreIsEditable; +} + +- (void)setEditable: (BOOL)editable +{ + theStoreIsEditable = editable; +} + +- (NSString *)name +{ + return theName; +} + +- (void)setName: (NSString *)aName +{ + NSNotificationCenter *defaultCenter; + + [aName retain]; + [theName release]; + theName = aName; + + defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName: LiFileStoresChangedNotification + object: nil + userInfo: nil]; +} + +- (NSImage *)icon +{ + return theIcon; +} + +- (void)setIcon: (NSImage *)anIcon +{ + NSNotificationCenter *defaultCenter; + + [anIcon retain]; + [theIcon release]; + theIcon = anIcon; + + defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName: LiFileStoresChangedNotification + object: nil + userInfo: nil]; +} + +- (NSMutableSet *)addedFiles +{ + if (theAddedFiles == nil) + [self setAddedFiles: [NSMutableSet set]]; + return theAddedFiles; +} + +- (void)setAddedFiles: (NSMutableSet *)aSet +{ + [aSet retain]; + [theAddedFiles release]; + theAddedFiles = aSet; +} + +- (NSMutableSet *)changedFiles +{ + if (theChangedFiles == nil) + [self setChangedFiles: [NSMutableSet set]]; + return theChangedFiles; +} + +- (void)setChangedFiles: (NSMutableSet *)aSet +{ + [aSet retain]; + [theChangedFiles release]; + theChangedFiles = aSet; +} + +- (NSMutableSet *)removedFiles +{ + if (theRemovedFiles == nil) + [self setRemovedFiles: [NSMutableSet set]]; + return theRemovedFiles; +} + +- (void)setRemovedFiles: (NSMutableSet *)aSet +{ + [aSet retain]; + [theRemovedFiles release]; + theRemovedFiles = aSet; +} +@end + +@implementation LiFileStore (Scripting) +- (NSScriptObjectSpecifier *)objectSpecifier +{ + NSScriptClassDescription *containerDescription; + NSScriptObjectSpecifier *containerRef; + unsigned index; + + index = [[LiFileStore allFileStores] indexOfObjectIdenticalTo: self]; + if (index != NSNotFound) { + containerRef = [NSApp objectSpecifier]; + containerDescription = (NSScriptClassDescription *)[NSScriptClassDescription classDescriptionForClass:[NSApp class]]; + + return [[[NSIndexSpecifier alloc] initWithContainerClassDescription:containerDescription containerSpecifier:containerRef key:@"orderedFileStores" index:index] autorelease]; + } else + return nil; +} +@end + +@implementation LiFileStore (Private) +// XXX +// Should coalesce like events into a single event before sending it +// and take the array code out of the individual file updates. +- (void)sendNotificationName: (NSString *)aNotificationName + userInfo: (NSDictionary *)userInfo +{ + NSNotificationCenter *defaultCenter; + + defaultCenter = [NSNotificationCenter defaultCenter]; + [defaultCenter postNotificationName: aNotificationName + object: self + userInfo: userInfo]; +} + +- (unsigned)sendNotifications +{ + NSMutableDictionary *userInfo; + unsigned changeCount; + + userInfo = [NSMutableDictionary dictionary]; + if ([[self addedFiles] count] > 0) { + [userInfo setObject: [[self addedFiles] allObjects] + forKey: LiFilesAdded]; + [self setAddedFiles: nil]; + } + if ([[self changedFiles] count] > 0) { + [userInfo setObject: [[self changedFiles] allObjects] + forKey: LiFilesChanged]; + [self setChangedFiles: nil]; + } + if ([[self removedFiles] count] > 0) { + [userInfo setObject: [[self removedFiles] allObjects] + forKey: LiFilesRemoved]; + [self setRemovedFiles: nil]; + } + + changeCount = [userInfo count]; + if (changeCount > 0) { + [self sendNotificationName: LiFileChangedNotification + userInfo: userInfo]; + } + return changeCount; +} + +- (void)sendAddNotificationForFileHandle: (LiFileHandle *)aFileHandle +{ + [[self addedFiles] addObject: aFileHandle]; +} + +- (void)sendUpdateNotificationForFileHandle: (LiFileHandle *)aFileHandle + oldAttributes: (NSDictionary *)oldAttrs +{ + if ([oldAttrs count] > 0) { + [[self changedFiles] addObject: + [NSDictionary dictionaryWithObjects: + [NSArray arrayWithObjects: aFileHandle, oldAttrs, nil] + forKeys: + [NSArray arrayWithObjects: LiFileHandleAttribute, LiFileOldAttributes, nil]]]; + } +} + +- (void)sendRemoveNotificationForFileHandle: (LiFileHandle *)aFileHandle + oldAttributes: (NSDictionary *)oldAttrs +{ + [[self removedFiles] addObject: + [NSDictionary dictionaryWithObjects: + [NSArray arrayWithObjects: aFileHandle, oldAttrs, nil] + forKeys: + [NSArray arrayWithObjects: LiFileHandleAttribute, LiFileOldAttributes, nil]]]; +} +@end
\ No newline at end of file diff --git a/Frameworks/LiBackend/LiFilter.h b/Frameworks/LiBackend/LiFilter.h new file mode 100644 index 0000000..3a81280 --- /dev/null +++ b/Frameworks/LiBackend/LiFilter.h @@ -0,0 +1,38 @@ +// +// LiFilter.h +// LiFrameworks +// +// Created by Brian Cully on Sat Aug 23 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +@interface LiFilter : NSObject +{ + NSString *theAttribute; + NSString *theCompareSelector; + id theValue; +} ++ (LiFilter *)filterWithAttribute: (NSString *)anAttribute + compareSelector: (SEL)aSelector + value: (id)aValue; + +- (id)initWithAttribute: (NSString *)anAttribute + compareSelector: (SEL)aSelector + value: (id)aValue; +@property (retain,getter=attribute) NSString *theAttribute; +@property (retain,getter=value) id theValue; +@property (retain) NSString *theCompareSelector; +@end + +@interface LiFilter (Accessors) +- (NSString *)attribute; +- (void)setAttribute: (NSString *)anAttribute; +- (SEL)compareSelector; +- (void)setCompareSelector: (SEL)aSelector; +- (id)value; +- (void)setValue: (id)aValue; +@end + +@interface LiFilter (CommonAccessors) +- (NSString *)description; +@end
\ No newline at end of file diff --git a/Frameworks/LiBackend/LiFilter.m b/Frameworks/LiBackend/LiFilter.m new file mode 100644 index 0000000..74e2f4a --- /dev/null +++ b/Frameworks/LiBackend/LiFilter.m @@ -0,0 +1,108 @@ +// +// LiFilter.m +// LiFrameworks +// +// Created by Brian Cully on Sat Aug 23 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +#import "LiFilter.h" + +@implementation LiFilter ++ (LiFilter *)filterWithAttribute: (NSString *)anAttribute + compareSelector: (SEL)aSelector + value: (id)aValue +{ + LiFilter *tmpFilter; + + tmpFilter = [[self alloc] initWithAttribute: anAttribute + compareSelector: aSelector + value: aValue]; + return [tmpFilter autorelease]; +} + +- (id)init +{ + NSException *exception; + + exception = [NSException exceptionWithName: @"LiNoInitException" + reason: @"[LiFilter init] not supported" + userInfo: nil]; + [exception raise]; + + return nil; +} + +- (void)dealloc +{ + [self setAttribute: nil]; + [self setCompareSelector: nil]; + [self setValue: nil]; + + [super dealloc]; +} + +- (id)initWithAttribute: (NSString *)anAttribute + compareSelector: (SEL)aSelector + value: (id)aValue +{ + self = [super init]; + + [self setAttribute: anAttribute]; + [self setCompareSelector: aSelector]; + [self setValue: aValue]; + + return self; +} +@synthesize theCompareSelector; +@synthesize theAttribute; +@synthesize theValue; +@end + +@implementation LiFilter (Accessors) +- (NSString *)attribute +{ + return theAttribute; +} + +- (void)setAttribute: (NSString *)anAttribute +{ + [anAttribute retain]; + [theAttribute release]; + theAttribute = anAttribute; +} + +- (SEL)compareSelector +{ + return NSSelectorFromString(theCompareSelector); +} + +- (void)setCompareSelector: (SEL)aSelector +{ + [theCompareSelector release]; + theCompareSelector = [NSStringFromSelector(aSelector) retain]; +} + +- (id)value +{ + return theValue; +} + +- (void)setValue: (id)aValue +{ + [aValue retain]; + [theValue release]; + theValue = aValue; +} +@end + +@implementation LiFilter (CommonAccessors) +- (NSString *)description +{ + NSString *desc; + + desc = [NSString stringWithFormat: @"{\n\tattribute: %@\n\tselector: %@\n\tvalue: %@\n}", + theAttribute, theCompareSelector, [theValue description]]; + return desc; +} +@end
\ No newline at end of file diff --git a/Frameworks/LiBackend/LiLog.h b/Frameworks/LiBackend/LiLog.h new file mode 100644 index 0000000..24043f0 --- /dev/null +++ b/Frameworks/LiBackend/LiLog.h @@ -0,0 +1,21 @@ +// +// LiLog.h +// Liaison +// +// Created by Brian Cully on Tue May 20 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +@interface LiLog : NSObject ++ (void)alertWithHeader: (NSString *)aHeader + contents: (NSString *)someContents; + ++ (void)logAsDebug: (NSString *)format, ...; ++ (void)logAsInfo: (NSString *)format, ...; ++ (void)logAsWarning: (NSString *)format, ...; ++ (void)logAsError: (NSString *)format, ...; + ++ (id)indentDebugLog; ++ (id)unindentDebugLog; ++ (NSString *)debugIndentString; +@end diff --git a/Frameworks/LiBackend/LiLog.m b/Frameworks/LiBackend/LiLog.m new file mode 100644 index 0000000..5dcb861 --- /dev/null +++ b/Frameworks/LiBackend/LiLog.m @@ -0,0 +1,104 @@ +// +// LiLog.m +// Liaison +// +// Created by Brian Cully on Tue May 20 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +#import "LiLog.h" + +@implementation LiLog +static int debugIndentLevel = 0; + ++ (void)alertDidEnd: (NSWindow *)sheet + returnCode: (int)returnCode + contextInfo: (void *)contextInfo +{ + [sheet close]; + + return; +} + ++ (void)alertWithHeader: (NSString *)aHeader + contents: (NSString *)someContents + forWindow: (NSWindow *)aWindow +{ + if (aWindow != nil) + NSBeginAlertSheet(aHeader, @"Okay", nil, nil, aWindow, self, + @selector(alertDidEnd:returnCode:contextInfo:), + @selector(alertDidEnd:returnCode:contextInfo:), + nil, someContents); + else + NSRunAlertPanel(aHeader, someContents, @"Okay", nil, nil); +} + ++ (void)alertWithHeader: (NSString *)aHeader + contents: (NSString *)someContents +{ + [self alertWithHeader: aHeader contents: someContents forWindow: [NSApp keyWindow]]; +} + ++ (void)logAsDebug: (NSString *)format, ... +{ +#define DEBUG 1 +#if DEBUG + va_list args; + + va_start(args, format); + NSLogv([[@"DEBUG: " stringByAppendingString: [self debugIndentString]] stringByAppendingString: format], args); + va_end(args); +#endif +} + ++ (void)logAsInfo: (NSString *)format, ... +{ + va_list args; + + va_start(args, format); + NSLogv([@"INFO: " stringByAppendingString: format], args); + va_end(args); +} + ++ (void)logAsWarning: (NSString *)format, ... +{ + va_list args; + + va_start(args, format); + NSLogv([@"WARNING: " stringByAppendingString: format], args); + va_end(args); +} + ++ (void)logAsError: (NSString *)format, ... +{ + va_list args; + + va_start(args, format); + NSLogv([@"ERROR: " stringByAppendingString: format], args); + va_end(args); +} + ++ (id)indentDebugLog +{ + debugIndentLevel++; + return self; +} + ++ (id)unindentDebugLog +{ + if (debugIndentLevel > 0) + debugIndentLevel--; + return self; +} + ++ (NSString *)debugIndentString +{ + NSMutableString *indentString; + int i; + + indentString = [NSMutableString string]; + for (i = 0; i < debugIndentLevel; i++) + [indentString appendString: @"\t"]; + return indentString; +} +@end diff --git a/Frameworks/LiBackend/LiPreferences.h b/Frameworks/LiBackend/LiPreferences.h new file mode 100644 index 0000000..390b67f --- /dev/null +++ b/Frameworks/LiBackend/LiPreferences.h @@ -0,0 +1,31 @@ +// +// Preferences.h +// Liaison +// +// Created by Brian Cully on Fri Feb 21 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +@interface Preferences : NSObject +{ + NSUserDefaults *theDefaults; +} + ++ (Preferences *)sharedPreferences; + +- (NSString *)downloadDirectory; +- (void)setDownloadDirectory: (NSString *)aPath; +- (NSString *)groupPath; +- (void)setGroupPath: (NSString *)aPath; +- (NSString *)libraryPath; +- (void)setLibraryPath: (NSString *)aPath; +- (NSString *)hostname; +- (void)setHostname: (NSString *)aHostname; +- (BOOL)networkEnabled; +- (void)setNetworkEnabled: (BOOL)isEnabled; +- (BOOL)useRendezvousGroup; +- (void)setUseRendezvousGroup: (BOOL)useGroup; +- (NSDictionary *)fileListPrefs; +- (void)setFileListPrefs: (NSDictionary *)listPrefs; +@property (retain) NSUserDefaults *theDefaults; +@end diff --git a/Frameworks/LiBackend/LiPreferences.m b/Frameworks/LiBackend/LiPreferences.m new file mode 100644 index 0000000..0f59581 --- /dev/null +++ b/Frameworks/LiBackend/LiPreferences.m @@ -0,0 +1,209 @@ +// +// Preferences.m +// Liaison +// +// Created by Brian Cully on Fri Feb 21 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +#import "LiPreferences.h" + +// Default download directory. +#define DOWNLOADSPATH @"/Desktop" + +// Default library datastore paths. +#define LIBRARYPATH @"/Library/Liaison/Liaison Library.xml" +#define GROUPPATH @"/Library/Liaison/Liaison Groups.xml" + +// Default hostname. +#define HOSTNAME @"Unknown" + +// User default keys. +#define DOWNLOADKEY @"downloadsDirectory" +#define GROUPPATHKEY @"groupPath" +#define HOSTNAMEKEY @"rendezvousHostname" +#define LIBRARYPATHKEY @"libraryPath" +#define NETWORKENABLEDKEY @"networkEnabled" +#define USERENDEZVOUSGROUPKEY @"useRendezvousGroup" +#define FILELISTPREFSKEY @"fileListPrefs" + +@implementation Preferences +static Preferences *sharedInstance = nil; + ++ (Preferences *)sharedPreferences +{ + if (sharedInstance == nil) + sharedInstance = [[Preferences alloc] init]; + return sharedInstance; +} + +- (id)init +{ + self = [super init]; + if (self) { + theDefaults = [NSUserDefaults standardUserDefaults]; + } + return self; +} + +- (void)dealloc +{ + [theDefaults synchronize]; + [super dealloc]; +} + +- (NSString *)defaultDownloadDirectory +{ + return [NSHomeDirectory() stringByAppendingPathComponent: + DOWNLOADSPATH]; +} + +- (NSString *)downloadDirectory +{ + NSString *downloadDirectory; + + downloadDirectory = [theDefaults objectForKey: DOWNLOADKEY]; + if (downloadDirectory == nil) + downloadDirectory = [self defaultDownloadDirectory]; + return downloadDirectory; +} + +- (void)setDownloadDirectory: (NSString *)aPath +{ + [theDefaults setObject: aPath forKey: DOWNLOADKEY]; +} + +- (NSString *)defaultGroupPath +{ + return [NSHomeDirectory() stringByAppendingPathComponent: GROUPPATH]; +} + +- (NSString *)groupPath +{ + NSString *groupPath; + + groupPath = [theDefaults objectForKey: GROUPPATHKEY]; + if (groupPath == nil) + groupPath = [self defaultGroupPath]; + return groupPath; +} + +- (void)setGroupPath: (NSString *)aPath +{ + [theDefaults setObject: aPath forKey: GROUPPATHKEY]; +} + +- (NSString *)defaultLibraryPath +{ + return [NSHomeDirectory() stringByAppendingPathComponent: LIBRARYPATH]; +} + +- (NSString *)libraryPath +{ + NSString *libraryPath; + + libraryPath = [theDefaults objectForKey: LIBRARYPATHKEY]; + if (libraryPath == nil) + libraryPath = [self defaultLibraryPath]; + return libraryPath; +} + +- (void)setLibraryPath: (NSString *)aPath +{ + [theDefaults setObject: aPath forKey: LIBRARYPATHKEY]; +} + +- (NSString *)defaultHostname +{ + NSArray *hostnames; + NSString *hostname; + + hostnames = [[NSHost currentHost] names]; + for (hostname in hostnames) { + NSRange localRange; + + localRange = [hostname rangeOfString: @".local."]; + if (localRange.location != NSNotFound) { + hostname = [hostname substringToIndex: localRange.location]; + break; + } + } + if (hostname == nil) + hostname = [hostnames objectAtIndex: 0]; + + return hostname; +} + +- (NSString *)hostname +{ + NSString *hostname; + + hostname = [theDefaults objectForKey: HOSTNAMEKEY]; + if (hostname == nil) + hostname = [self defaultHostname]; + return hostname; +} + +- (void)setHostname: (NSString *)aHostname +{ + [theDefaults setObject: aHostname forKey: HOSTNAMEKEY]; +} + +- (BOOL)defaultNetworkEnabled +{ + return YES; +} + +- (BOOL)networkEnabled +{ + NSNumber *networkEnabled; + + networkEnabled = [theDefaults objectForKey: NETWORKENABLEDKEY]; + if (networkEnabled == nil) + return [self defaultNetworkEnabled]; + if ([networkEnabled intValue] == 1) + return YES; + else + return NO; +} +- (void)setNetworkEnabled: (BOOL)isEnabled +{ + if (isEnabled) + [theDefaults setObject: [NSNumber numberWithInt: 1] + forKey: NETWORKENABLEDKEY]; + else + [theDefaults setObject: [NSNumber numberWithInt: 0] + forKey: NETWORKENABLEDKEY]; +} + +- (BOOL)defaultUseRendezvousGroup +{ + return NO; +} + +- (BOOL)useRendezvousGroup +{ + NSNumber *useRendezvousGroup; + + useRendezvousGroup = [theDefaults objectForKey: USERENDEZVOUSGROUPKEY]; + if (useRendezvousGroup == nil) + return [self defaultUseRendezvousGroup]; + + return [useRendezvousGroup boolValue]; +} +- (void)setUseRendezvousGroup: (BOOL)useGroup +{ + [theDefaults setObject: [NSNumber numberWithBool: useGroup] + forKey: USERENDEZVOUSGROUPKEY]; +} + +- (NSDictionary *)fileListPrefs +{ + return [theDefaults objectForKey: FILELISTPREFSKEY]; +} +- (void)setFileListPrefs: (NSDictionary *)listPrefs +{ + [theDefaults setObject: listPrefs forKey: FILELISTPREFSKEY]; +} +@synthesize theDefaults; +@end diff --git a/Frameworks/LiBackend/LiStoreValidator.h b/Frameworks/LiBackend/LiStoreValidator.h new file mode 100644 index 0000000..da5094e --- /dev/null +++ b/Frameworks/LiBackend/LiStoreValidator.h @@ -0,0 +1,11 @@ +// +// LiStoreValidator.h +// Liaison +// +// Created by Brian Cully on Sun May 25 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +@interface LiStoreValidator : NSObject +- (void)addFileToUpdateQueue: (LiFileHandle *)aFileHandle; +@end diff --git a/Frameworks/LiBackend/LiStoreValidator.m b/Frameworks/LiBackend/LiStoreValidator.m new file mode 100644 index 0000000..3997cd5 --- /dev/null +++ b/Frameworks/LiBackend/LiStoreValidator.m @@ -0,0 +1,13 @@ +// +// LiStoreValidator.m +// Liaison +// +// Created by Brian Cully on Sun May 25 2003. +// Copyright (c) 2003 Brian Cully. All rights reserved. +// + +@implementation LiStoreValidator +- (void)addFileToUpdateQueue: (LiFileHandle *)aFileHandle +{ +} +@end |