From 42e76eae727dcb12b072ce8b104a09250f8c64c3 Mon Sep 17 00:00:00 2001 From: David Ayers Date: Sun, 2 Oct 2005 16:09:42 +0000 Subject: [PATCH] * EOControl/EOKeyValueCoding.h/m (unableToSetNullForKey:): Remove deprecated -base/Foundation hook. (setNilValueForKey:) Override new hook to call unableToSetNilForKey:. (unableToSetNilForKey:): Raise exception as documented. (takeValue:forKey:): Implement here to avoid deprecation warning. (takeValue:forKeyPath:): Ditto. (takeValuesFromDictionary:): Ditto. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@21767 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 8 +++ EOControl/EOKeyValueCoding.h | 16 ++++-- EOControl/EOKeyValueCoding.m | 108 +++++++++++++++++++++++++++++++---- 3 files changed, 116 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index e776296..fc6fe71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,14 @@ * EOControl/EOOrQualifier.m: ([-description]) Make qualifiers user presentable like in WO. (-[debugDescription]): New deprecated method for old description. + + * EOControl/EOKeyValueCoding.h/m + (unableToSetNullForKey:): Remove deprecated -base/Foundation hook. + (setNilValueForKey:) Override new hook to call unableToSetNilForKey:. + (unableToSetNilForKey:): Raise exception as documented. + (takeValue:forKey:): Implement here to avoid deprecation warning. + (takeValue:forKeyPath:): Ditto. + (takeValuesFromDictionary:): Ditto. 2005-08-25 Manuel Guesdon diff --git a/EOControl/EOKeyValueCoding.h b/EOControl/EOKeyValueCoding.h index 5d5c2e7..691a5df 100644 --- a/EOControl/EOKeyValueCoding.h +++ b/EOControl/EOKeyValueCoding.h @@ -58,7 +58,9 @@ - (id)valueForKey: (NSString *)key; /** - * Unimplemented here. Relies on NSKeyValueCoding. + * Overrides the implementation of gnustep-base/Foundation this method + * is currently deprecated in favor of setValue:forKey: yet we aim + * to maintain WebObjects 4.5 compatibility. */ - (void)takeValue: (id)value forKey: (NSString *)key; @@ -103,10 +105,10 @@ /** * This method is invoked by the EOKeyValueCoding mechanism when an attempt - * is made to set an null value for a scalar attribute. This implementation - * raises an NSInvalidArgument exception.
+ * is made to set an null value for a scalar attribute. * Contrary to the TOC of the documentation, this method is called * unableToSetNilForKey: and not unableToSetNullForKey:
+ * This implementation raises an NSInvalidArgument exception.
* The NSKeyValueCoding -setNilValueForKey: is overriden to invoke this * method instead. We manipulate the runtime to insure that our implementation * of unableToSetNilForKey: is used in favor of the one in gnustep-base or @@ -124,7 +126,9 @@ - (id)valueForKeyPath: (NSString *)keyPath; /** - * Unimplemented here. Relies on NSKeyValueCoding. + * Overrides the implementation of gnustep-base/Foundation this method + * is currently deprecated in favor of setValue:forKeyPath: yet we aim + * to maintain WebObjects 4.5 compatibility. */ - (void)takeValue: (id)value forKeyPath: (NSString *)keyPath; @@ -134,7 +138,9 @@ - (NSDictionary *)valuesForKeys: (NSArray *)keys; /** - * Unimplemented here. Relies on NSKeyValueCoding. + * Overrides the implementation of gnustep-base/Foundation this method + * is currently deprecated in favor of setValue:forKeyPath: yet we aim + * to maintain WebObjects 4.5 compatibility. */ - (void)takeValuesFromDictionary: (NSDictionary *)dictionary; diff --git a/EOControl/EOKeyValueCoding.m b/EOControl/EOKeyValueCoding.m index d086ddd..b39b624 100644 --- a/EOControl/EOKeyValueCoding.m +++ b/EOControl/EOKeyValueCoding.m @@ -104,15 +104,22 @@ initialize(void) @selector(GDL2KVCNSObjectICategoryID), YES); } -- (void) unableToSetNullForKey: (NSString *)key + +/* This is what -base(add) will call. It should invoke what the API + specifies should be overridden. */ +- (void) setNilValueForKey: (NSString*)aKey { - GSOnceMLog(@"This method is deprecated, use -unableToSetNilForKey:!"); - [self unableToSetNilForKey: key]; + [self unableToSetNilForKey: aKey]; } -- (void) setNilValueForKey: (NSString *)key + +/* This is what should be overridden according to the API.*/ +- (void) unableToSetNilForKey: (NSString *)key { - [self unableToSetNilForKey: key]; + [NSException raise: NSInvalidArgumentException + format: @"%@ -- %@ 0x%x: Given nil value to set for key \"%@\"", + NSStringFromSelector(_cmd), NSStringFromClass([self class]), + self, key]; } /* See EODeprecated.h. */ @@ -125,14 +132,93 @@ initialize(void) { } -/* See header file for documentation. */ -- (void) unableToSetNilForKey: (NSString *)key +- (void) takeValue: (id)anObject forKey: (NSString*)aKey { - [NSException raise: NSInvalidArgumentException - format: @"%@ -- %@ 0x%x: Given nil value to set for key \"%@\"", - NSStringFromSelector(_cmd), NSStringFromClass([self class]), - self, key]; + SEL sel = 0; + const char *type = 0; + int off; + unsigned size = [aKey length]; + + if (size > 0) + { + const char *name; + char buf[size+6]; + char lo; + char hi; + + strcpy(buf, "_set"); + [aKey getCString: &buf[4]]; + lo = buf[4]; + hi = islower(lo) ? toupper(lo) : lo; + buf[4] = hi; + buf[size+4] = ':'; + buf[size+5] = '\0'; + + name = &buf[1]; // setKey: + type = NULL; + sel = GSSelectorFromName(name); + if (sel == 0 || [self respondsToSelector: sel] == NO) + { + name = buf; // _setKey: + sel = GSSelectorFromName(name); + if (sel == 0 || [self respondsToSelector: sel] == NO) + { + sel = 0; + if ([[self class] accessInstanceVariablesDirectly] == YES) + { + buf[size+4] = '\0'; + buf[3] = '_'; + buf[4] = lo; + name = &buf[4]; // key + if (GSObjCFindVariable(self, name, &type, &size, &off) == NO) + { + name = &buf[3]; // _key + GSObjCFindVariable(self, name, &type, &size, &off); + } + } + } + } + } + GSObjCSetValue(self, aKey, anObject, sel, type, size, off); } + + +- (void) takeValue: (id)anObject forKeyPath: (NSString*)aKey +{ + NSRange r = [aKey rangeOfString: @"."]; + + if (r.length == 0) + { + [self takeValue: anObject forKey: aKey]; + } + else + { + NSString *key = [aKey substringToIndex: r.location]; + NSString *path = [aKey substringFromIndex: NSMaxRange(r)]; + + [[self valueForKey: key] takeValue: anObject forKeyPath: path]; + } +} + + +- (void) takeValuesFromDictionary: (NSDictionary*)aDictionary +{ + NSEnumerator *enumerator = [aDictionary keyEnumerator]; + NSNull *null = [NSNull null]; + NSString *key; + + while ((key = [enumerator nextObject]) != nil) + { + id obj = [aDictionary objectForKey: key]; + + if (obj == null) + { + obj = nil; + } + [self takeValue: obj forKey: key]; + } +} + @end