diff --git a/ChangeLog b/ChangeLog index 24684e924..c0e644d07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-12-01 Wolfgang Sourdeau + + * SoObjects/SOGo/SOGoDefaultsSource.m (-boolForKey:) + (-floatForKey:, -integerForKey:, -dataForKey:, -stringForKey:) + (-dictionaryForKey:, -arrayForKey:, -stringArrayForKey:): added + type checking and warnings. + 2009-11-30 Wolfgang Sourdeau * SoObjects/SOGo/SOGoDefaultsSource.m (-setBool:forKey:): we @@ -6,7 +13,7 @@ code. * UI/WebServerResources/SchedulerUI.js (initCalendars): the - "ShowCompletedTasks" parameter is in the UserSettings dictionary. + "ShowCompletedTasks" parameter is in the UserSettings dictionary. * SoObjects/SOGo/SOGoDefaultsSource.m (-migrateOldDefaultsWithDictionary:): when migrating between two diff --git a/SoObjects/SOGo/SOGoDefaultsSource.h b/SoObjects/SOGo/SOGoDefaultsSource.h index 47b0dad46..741293950 100644 --- a/SoObjects/SOGo/SOGoDefaultsSource.h +++ b/SoObjects/SOGo/SOGoDefaultsSource.h @@ -74,7 +74,7 @@ extern NSString *SOGoDefaultsSourceUnmutableSource; - (void) setInteger: (int) value forKey: (NSString *) key; - (int) integerForKey: (NSString *) key; -- (id) dictionaryForKey: (NSString *) key; +- (NSDictionary *) dictionaryForKey: (NSString *) key; - (NSData *) dataForKey: (NSString *) key; - (NSString *) stringForKey: (NSString *) key; diff --git a/SoObjects/SOGo/SOGoDefaultsSource.m b/SoObjects/SOGo/SOGoDefaultsSource.m index d5004303a..77307c0c4 100644 --- a/SoObjects/SOGo/SOGoDefaultsSource.m +++ b/SoObjects/SOGo/SOGoDefaultsSource.m @@ -34,8 +34,25 @@ NSString *SOGoDefaultsSourceInvalidSource = @"SOGoDefaultsSourceInvalidSource"; NSString *SOGoDefaultsSourceUnmutableSource = @"SOGoDefaultsSourceUnmutableSource"; +static Class NSArrayKlass = Nil; +static Class NSDataKlass = Nil; +static Class NSDictionaryKlass = Nil; +static Class NSStringKlass = Nil; + @implementation SOGoDefaultsSource ++ (void) initialize +{ + if (!NSArrayKlass) + NSArrayKlass = [NSArray class]; + if (!NSDataKlass) + NSDataKlass = [NSData class]; + if (!NSDictionaryKlass) + NSDictionaryKlass = [NSDictionary class]; + if (!NSStringKlass) + NSStringKlass = [NSString class]; +} + + (id) defaultsSourceWithSource: (id) newSource andParentSource: (SOGoDefaultsSource *) newParentSource { @@ -128,7 +145,25 @@ NSString *SOGoDefaultsSourceUnmutableSource = @"SOGoDefaultsSourceUnmutableSourc - (BOOL) boolForKey: (NSString *) key { - return [[self objectForKey: key] boolValue]; + id boolForKey; + BOOL value; + + boolForKey = [self objectForKey: key]; + if (boolForKey) + { + if ([boolForKey respondsToSelector: @selector (boolValue)]) + value = [boolForKey boolValue]; + else + { + [self warnWithFormat: @"expected a boolean for '%@' (ignored)", + key]; + value = NO; + } + } + else + value = NO; + + return value; } - (void) setFloat: (float) value @@ -140,7 +175,25 @@ NSString *SOGoDefaultsSourceUnmutableSource = @"SOGoDefaultsSourceUnmutableSourc - (float) floatForKey: (NSString *) key { - return [[self objectForKey: key] floatValue]; + id floatForKey; + float value; + + floatForKey = [self objectForKey: key]; + if (floatForKey) + { + if ([floatForKey respondsToSelector: @selector (floatValue)]) + value = [floatForKey floatValue]; + else + { + [self warnWithFormat: @"expected a float for '%@' (ignored)", + key]; + value = 0.0; + } + } + else + value = 0.0; + + return value; } - (void) setInteger: (int) value @@ -152,39 +205,107 @@ NSString *SOGoDefaultsSourceUnmutableSource = @"SOGoDefaultsSourceUnmutableSourc - (int) integerForKey: (NSString *) key { - return [[self objectForKey: key] intValue]; -} + id intForKey; + int value; -#warning TODO: type checking -- (NSArray *) arrayForKey: (NSString *) key -{ - return [self objectForKey: key]; -} + intForKey = [self objectForKey: key]; + if (intForKey) + { + if ([intForKey respondsToSelector: @selector (intValue)]) + value = [intForKey intValue]; + else + { + [self warnWithFormat: @"expected an integer for '%@' (ignored)", + key]; + value = 0; + } + } + else + value = 0; -- (NSArray *) stringArrayForKey: (NSString *) key -{ - return [self objectForKey: key]; + return value; } - (NSData *) dataForKey: (NSString *) key { - return [self objectForKey: key]; + NSData *dataForKey; + + dataForKey = [self objectForKey: key]; + if (dataForKey && ![dataForKey isKindOfClass: NSDataKlass]) + { + [self warnWithFormat: @"expected an NSData for '%@' (ignored)", + key]; + dataForKey = nil; + } + + return dataForKey; } - (NSString *) stringForKey: (NSString *) key { - return [self objectForKey: key]; + NSString *stringForKey; + + stringForKey = [self objectForKey: key]; + if (stringForKey && ![stringForKey isKindOfClass: NSStringKlass]) + { + [self warnWithFormat: @"expected an NSString for '%@' (ignored)", + key]; + stringForKey = nil; + } + + return stringForKey; } -/* Dictionaries are a special case for which we don't allow searches in the - parent source. Each level can thus have its own set of dictionary values. */ -- (id) dictionaryForKey: (NSString *) objectKey +- (NSDictionary *) dictionaryForKey: (NSString *) key { - id objectForKey; + NSDictionary *dictionaryForKey; - objectForKey = [source objectForKey: objectKey]; + /* Dictionaries are a special case for which we don't allow searches in the + parent source. Each level can thus have its own set of dictionary + values. */ + dictionaryForKey = [source objectForKey: key]; + if (dictionaryForKey + && ![dictionaryForKey isKindOfClass: NSDictionaryKlass]) + { + [self warnWithFormat: @"expected an NSDictionary for '%@' (ignored)", + key]; + dictionaryForKey = nil; + } - return objectForKey; + return dictionaryForKey; +} + +- (NSArray *) arrayForKey: (NSString *) key +{ + NSArray *arrayForKey; + + arrayForKey = [self objectForKey: key]; + if (arrayForKey && ![arrayForKey isKindOfClass: NSArrayKlass]) + { + [self warnWithFormat: @"expected an NSArray for '%@' (ignored)", + key]; + arrayForKey = nil; + } + + return arrayForKey; +} + +- (NSArray *) stringArrayForKey: (NSString *) key +{ + NSArray *stringArray; + int count, max; + + stringArray = [self arrayForKey: key]; + for (count = 0; stringArray && count < max; count++) + if (![[stringArray objectAtIndex: count] isKindOfClass: NSStringKlass]) + { + [self warnWithFormat: @"expected string value in array for '%@'" + @", value %d is not a string (ignored)", + key, count]; + stringArray = nil; + } + + return stringArray; } - (BOOL) migrate diff --git a/SoObjects/SOGo/SOGoUserDefaults.h b/SoObjects/SOGo/SOGoUserDefaults.h index a81255d34..45807ab49 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.h +++ b/SoObjects/SOGo/SOGoUserDefaults.h @@ -26,7 +26,7 @@ #import @class NSArray; -@class NSMutableDictionary; +@class NSDictionary; @class NSString; @class NSTimeZone; @@ -140,11 +140,11 @@ extern NSString *SOGoWeekStartFirstFullWeek; - (void) setRemindWithASound: (BOOL) newValue; - (BOOL) remindWithASound; -- (void) setVacationOptions: (NSMutableDictionary *) newValue; -- (NSMutableDictionary *) vacationOptions; +- (void) setVacationOptions: (NSDictionary *) newValue; +- (NSDictionary *) vacationOptions; -- (void) setForwardOptions: (NSMutableDictionary *) newValue; -- (NSMutableDictionary *) forwardOptions; +- (void) setForwardOptions: (NSDictionary *) newValue; +- (NSDictionary *) forwardOptions; @end diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index e39bacd43..13d5812cb 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -540,22 +540,22 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return [self boolForKey: @"SOGoRemindWithASound"]; } -- (void) setVacationOptions: (NSMutableDictionary *) newValue +- (void) setVacationOptions: (NSDictionary *) newValue { [self setObject: newValue forKey: @"Vacation"]; } -- (NSMutableDictionary *) vacationOptions +- (NSDictionary *) vacationOptions { return [self dictionaryForKey: @"Vacation"]; } -- (void) setForwardOptions: (NSMutableDictionary *) newValue +- (void) setForwardOptions: (NSDictionary *) newValue { [self setObject: newValue forKey: @"Forward"]; } -- (NSMutableDictionary *) forwardOptions +- (NSDictionary *) forwardOptions { return [self dictionaryForKey: @"Forward"]; } diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index 34ded3258..c764df15a 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -32,12 +32,13 @@ #import #import -#import -#import -#import -#import -#import -#import +#import +#import +#import +#import +#import +#import +#import #import diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index f3049b56f..0fbabb36e 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -79,24 +79,22 @@ dd = [user domainDefaults]; if ([dd vacationEnabled]) { - vacationOptions = [userDefaults vacationOptions]; + vacationOptions = [[userDefaults vacationOptions] mutableCopy]; if (!vacationOptions) { - vacationOptions = [NSMutableDictionary dictionary]; + vacationOptions = [NSMutableDictionary new]; [userDefaults setVacationOptions: vacationOptions]; } - [vacationOptions retain]; } if ([dd forwardEnabled]) { - forwardOptions = [userDefaults forwardOptions]; + forwardOptions = [[userDefaults forwardOptions] mutableCopy]; if (!forwardOptions) { - forwardOptions = [NSMutableDictionary dictionary]; + forwardOptions = [NSMutableDictionary new]; [userDefaults setForwardOptions: forwardOptions]; } - [forwardOptions retain]; } }