libs-gsweb/GSWeb.framework/GSWAssociation.m
Manuel Guesdon a34ef71f50 2002-03-07 Manuel Guesdon <mguesdon@orange-concept.com>
* GSWeb.framework/GSWAdaptor.h/.m:
		o added -isMultiThreadEnabled
		o method parameters names changes to conform to coding standards
	* GSWeb.framework/GSWResponse.h:
		o method parameters names changes to conform to coding standards
		o added missing method declarations
	* GSWeb.framework/GSWTemplateParserXML.m:
		o remove some 'error' messages from xml parser
	* GSWExtensions.framework/Makefile.preamble:
		o various changes (debug flags,...)
	* GSWExtensionsGSW.framework/Makefile.preamble:
		o various changes (debug flags,...)
	* GSWeb.framework/Makefile.preamble:
		o various changes (debug flags,libwrap,...)
	* GSWeb.framework/GSWDebug.h:
		o debug flags changes
	* GSWExtensions.framework/GSWExceptionPage.gswc/GSWExceptionPage.gswd:
		o change .gif to .mng
	* GSWExtensions.framework/GSWPageRestorationErrorPage.gswc/GSWPageRestorationErrorPage.gswd:
		o change .gif to .mng
	* GSWExtensions.framework/GSWSessionCreationErrorPage.gswc/GSWSessionCreationErrorPage.gswd:
		o change .gif to .mng
	* GSWeb.framework/GSWConfig.h: added GSWOPTVALUE_AdaptorHost
	* GSWeb.framework/GSWConstants.h/.m: added GSWOPT_AdaptorHost
	* GSWeb.framework/GSWApplication.m: added GSWOPT_AdaptorHost default value
	* GSWeb.framework/GSWDefaultAdaptor.h/.m:
		o adding connection refuse feature
		o added ivar adaptorHost
		o added host and port in "Waiting for connections" message
		o ivar names changes to conform to coding standards
	* GSWeb.framework/GSWDefaultAdaptorThread.m:
		o adding connection refuse feature
		o ivar names changes to conform to coding standards
	* GSWeb.framework/GSWComponent.m:
		o logs
	* GSWeb.framework/GSWDeployedBundle.m:
		o Search WebServer resources in Resources/WebServer/ instead of WebServerResources
	* GSWeb.framework/GSWProjectBundle.m
		o bug fix for wonames
	* GSWExtensions.framework/GSWDictionaryRepetition.h/m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWCollapsibleComponentContent.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWExceptionPage.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWIFrame.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWMetaRefresh.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWPageRestorationErrorPage.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWRedirect.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWSessionRestorationErrorPage.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWSessionCreationErrorPage.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensions.framework/GSWStatsPage.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensionsGSW.framework/GSWFileUploadFormComponent.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensionsGSW.framework/GSWSimpleFormComponent.h/.m:
		o ivar names changes to conform to coding standards
	* GSWExtensionsGSW.framework/GSWTabComponent.m:
		o ivar names changes to conform to coding standards
	* GSWExtensionsGSW.framework/GSWValidationFailureComponent.h/.m:
		o ivar names changes to conform to coding standards


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@13029 72102866-910b-0410-8b05-ffd578937521
2002-03-06 23:13:23 +00:00

1029 lines
31 KiB
Objective-C

/* GSWAssociation.m - GSWeb: Class GSWAssociation
Copyright (C) 1999 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com>
Date: Jan 1999
This file is part of the GNUstep Web Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
static char rcsId[] = "$Id$";
#include <GSWeb/GSWeb.h>
#include <math.h>
#if !defined(__NetBSD__)
#include <values.h>
#endif
static NSDictionary* localMinMaxDictionary=nil;
static NSMutableDictionary* associationsHandlerClasses=nil;
static NSLock* associationsLock=nil;
static NSMutableArray* associationsLogsHandlerClasses=nil;
//====================================================================
@implementation GSWAssociation
+(void)initialize
{
if (self==[GSWAssociation class])
{
associationsLock=[NSLock new];
if (!localMinMaxDictionary)
{
localMinMaxDictionary=[[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithShort:SCHAR_MIN],@"SCHAR_MIN",
[NSNumber numberWithShort:SCHAR_MAX],@"SCHAR_MAX",
[NSNumber numberWithShort:UCHAR_MAX],@"UCHAR_MAX",
[NSNumber numberWithShort:CHAR_MIN],@"CHAR_MIN",
[NSNumber numberWithShort:CHAR_MAX],@"CHAR_MAX",
[NSNumber numberWithShort:SHRT_MIN],@"SHRT_MIN",
[NSNumber numberWithShort:SHRT_MAX],@"SHRT_MAX",
[NSNumber numberWithUnsignedInt:0],@"USHRT_MIN",
[NSNumber numberWithUnsignedInt:USHRT_MAX],@"USHRT_MAX",
[NSNumber numberWithInt:INT_MIN],@"INT_MIN",
[NSNumber numberWithInt:INT_MAX],@"INT_MAX",
[NSNumber numberWithUnsignedInt:0],@"UINT_MIN",
[NSNumber numberWithUnsignedInt:UINT_MAX],@"UINT_MAX",
[NSNumber numberWithLong:LONG_MIN],@"LONG_MIN",
[NSNumber numberWithLong:LONG_MAX],@"LONG_MAX",
[NSNumber numberWithUnsignedLong:0],@"ULONG_MIN",
[NSNumber numberWithUnsignedLong:ULONG_MAX],@"ULONG_MAX",
#ifdef LONG_LONG_MAX
[NSNumber numberWithLongLong:LONG_LONG_MIN],@"LONG_LONG_MIN",
[NSNumber numberWithLongLong:LONG_LONG_MAX],@"LONG_LONG_MAX",
#endif
#ifdef ULONG_LONG_MAX
[NSNumber numberWithUnsignedLongLong:0],@"ULONG_LONG_MIN",
[NSNumber numberWithUnsignedLongLong:ULONG_LONG_MAX],@"ULONG_LONG_MAX",
#endif
[NSNumber numberWithFloat:FLT_MIN],@"FLOAT_MIN",
[NSNumber numberWithFloat:FLT_MAX],@"FLOAT_MAX",
[NSNumber numberWithFloat:DBL_MIN],@"DOUBLE_MIN",
[NSNumber numberWithFloat:DBL_MAX],@"DOUBLE_MAX",
nil,nil]
retain];
};
};
};
//--------------------------------------------------------------------
+(void)dealloc
{
DESTROY(localMinMaxDictionary);
DESTROY(associationsHandlerClasses);
DESTROY(associationsLogsHandlerClasses);
DESTROY(associationsLock);
};
//--------------------------------------------------------------------
// init
-(id)init
{
if ((self=[super init]))
{
};
return self;
};
-(void)dealloc
{
DESTROY(bindingName);
DESTROY(declarationName);
DESTROY(declarationType);
[super dealloc];
};
//--------------------------------------------------------------------
-(id)copyWithZone:(NSZone*)zone;
{
GSWAssociation* clone = [[isa allocWithZone:zone] init];
clone->debugEnabled=debugEnabled;
[clone setDebugEnabledForBinding:bindingName
declarationName:declarationName
declarationType:declarationType];
return clone;
};
//--------------------------------------------------------------------
-(NSString*)description
{
GSWLogAssertGood(self);
LOGObjectFnNotImplemented(); //TODOFN
return [super description];
};
//--------------------------------------------------------------------
-(NSString*)bindingName
{
return bindingName;
};
//--------------------------------------------------------------------
-(NSString*)declarationName
{
return declarationName;
};
//--------------------------------------------------------------------
-(NSString*)declarationType
{
return declarationType;
};
//--------------------------------------------------------------------
// isValueConstant
-(BOOL)isValueConstant
{
//OK
[self subclassResponsibility:_cmd];
return NO;
};
//--------------------------------------------------------------------
// isValueSettable
- (BOOL)isValueSettable
{
//OK
[self subclassResponsibility:_cmd];
return NO;
};
//--------------------------------------------------------------------
// setValue:inObject:
//NDFN
-(void)setValue:(id)value_
inObject:(id)object_
{
//OK
[self subclassResponsibility:_cmd];
};
//--------------------------------------------------------------------
// setValue:inComponent:
-(void)setValue:(id)value_
inComponent:(GSWComponent*)component_
{
//OK
[self setValue:value_
inObject:component_];
};
//--------------------------------------------------------------------
// valueInObject:
//NDFN
-(id)valueInObject:(id)object_
{
//OK
return [self subclassResponsibility:_cmd];
};
//--------------------------------------------------------------------
// valueInComponent:
-(id)valueInComponent:(GSWComponent*)component_;
{
//OK
return [self valueInObject:component_];
};
@end
//====================================================================
@implementation GSWAssociation (GSWAssociationCreation)
//--------------------------------------------------------------------
// associationWithKeyPath:
+(GSWAssociation*)associationWithKeyPath:(NSString*)keyPath_
{
//OK
if (keyPath_)
{
if ([keyPath_ hasPrefix:@"^"]
|| (!WOStrictFlag && [keyPath_ hasPrefix:@"~"]))
return [[[GSWBindingNameAssociation alloc]initWithKeyPath:keyPath_] autorelease];
else
return [[[GSWKeyValueAssociation alloc]initWithKeyPath:keyPath_] autorelease];
}
else
return nil;
};
//--------------------------------------------------------------------
// associationWithValue:
+(GSWAssociation*)associationWithValue:(id)value_
{
//OK
return [[[GSWConstantValueAssociation alloc]initWithValue:value_] autorelease];
};
//--------------------------------------------------------------------
// associationFromString:
//NDFN
+(GSWAssociation*)associationFromString:(NSString*)string_
{
GSWAssociation* _assoc=nil;
LOGClassFnStart();
NSDebugMLLog(@"associations",@"string_=[%@]",string_);
if ([string_ length]<=0)
_assoc=[self associationWithValue:string_];
else
{
NSString* _trimmedString=[string_ stringByTrimmingSpaces];
if ([_trimmedString isEqualToString:NSTYES])
{
_assoc=[self associationWithValue:[NSNumber numberWithBool:YES]];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
}
else if ([_trimmedString isEqualToString:NSTNO])
{
_assoc=[self associationWithValue:[NSNumber numberWithBool:NO]];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
}
else if ([_trimmedString hasPrefix:@"^"])
{
_assoc=[self associationWithKeyPath:_trimmedString];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
}
else if ([_trimmedString hasPrefix:@"\""])
{
if ([_trimmedString hasSuffix:@"\""])
{
_assoc=[self associationWithValue:[[_trimmedString stringWithoutPrefix:@"\""] stringWithoutSuffix:@"\""]];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
}
else
{
ExceptionRaise(@"GSWAssociation",@"String '%@' start with a \" but doesn't finish with a \"",
_trimmedString);
};
}
else if ([_trimmedString hasPrefix:@"\'"])
{
if ([_trimmedString hasSuffix:@"\'"])
{
_assoc=[self associationWithValue:[[_trimmedString stringWithoutPrefix:@"\'"] stringWithoutSuffix:@"\'"]];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
}
else
{
ExceptionRaise(@"GSWAssociation",@"String '%@' start with a character ' but doesn't finish with a character '",
_trimmedString);
};
}
else if ([_trimmedString hasPrefix:@"#"])
{
NSString* _numberString=[_trimmedString stringWithoutPrefix:@"#"];
//char* cString=[_numberString lossyCString];//TODO
char* cString=[_numberString cString];//TODO
char* endPtr=NULL;
int _value=strtol(cString,&endPtr,16);
NSDebugMLLog(@"associations",@"_value=[%d]",_value);
if (endPtr && *endPtr)
{
ExceptionRaise(@"GSWAssociation",@"String '%@' start with a '#' but doesn't countain an hexadecimal number (on %dth Character)",
_trimmedString,
(int)(endPtr-cString+1));
};
_assoc=[self associationWithValue:[NSNumber numberWithInt:_value]];
}
else
{
NSNumber*_limit=[localMinMaxDictionary objectForKey:_trimmedString];
NSDebugMLLog(@"associations",@"_limit=[%@]",_limit);
if (_limit)
{
_assoc=[self associationWithValue:_limit];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
}
else
{
NSCharacterSet* _cset=[NSCharacterSet characterSetWithCharactersInString:@"-+0123456789"];
NSRange _firstCharRange=[_trimmedString rangeOfCharacterFromSet:_cset
options:0
range:NSMakeRange(0,1)];
NSDebugMLLog(@"associations",@"_firstCharRange.length=%d _firstCharRange.location=%d ",_firstCharRange.length,_firstCharRange.location);
if (_firstCharRange.length==0 || _firstCharRange.location!=0)
{
_assoc=[self associationWithKeyPath:_trimmedString];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
}
else
{
//char* cString=[_trimmedString lossyCString];//TODO
char* cString=[_trimmedString cString];//TODO
char* endPtr=NULL;
int _value=strtol(cString,&endPtr,10);
NSDebugMLLog(@"associations",@"_value=[%d]",_value);
if (endPtr && *endPtr)
{
NSDebugMLLog(@"associations",@"endPtr=[%s]",endPtr);
NSDebugMLLog(@"associations",@"_value=[%d]",_value);
ExceptionRaise(@"GSWAssociation",
@"String '%@' must be a good number",
_trimmedString);
};
_assoc=[self associationWithValue:[NSNumber numberWithInt:_value]];
NSDebugMLLog(@"associations",@"_assoc=[%@]",_assoc);
};
};
};
};
LOGClassFnStop();
return _assoc;
};
//====================================================================
@implementation GSWAssociation (GSWAssociationHandlers)
//--------------------------------------------------------------------
+(void)setClasse:(Class)class_
forHandler:(NSString*)handler_
{
LOGClassFnStart();
NSDebugMLLog(@"associations",@"class_=%@",class_);
NSDebugMLLog(@"associations",@"handler_=%@",handler_);
TmpLockBeforeDate(associationsLock,[NSDate dateWithTimeIntervalSinceNow:GSLOCK_DELAY_S]);
if (!associationsHandlerClasses)
{
if (class_)
associationsHandlerClasses=[NSMutableDictionary new];
};
if (class_)
[associationsHandlerClasses setObject:class_
forKey:handler_];
else if (associationsHandlerClasses)
[associationsHandlerClasses removeObjectForKey:handler_];
TmpUnlock(associationsLock);
LOGClassFnStop();
};
//--------------------------------------------------------------------
+(void)addLogHandlerClasse:(Class)class_
{
LOGClassFnStart();
NSDebugMLLog(@"associations",@"class_=%@",class_);
TmpLockBeforeDate(associationsLock,[NSDate dateWithTimeIntervalSinceNow:GSLOCK_DELAY_S]);
if (!associationsLogsHandlerClasses)
{
if (class_)
associationsLogsHandlerClasses=[NSMutableArray new];
};
if (class_)
[associationsLogsHandlerClasses addObject:class_];
TmpUnlock(associationsLock);
LOGClassFnStop();
};
//--------------------------------------------------------------------
+(void)removeLogHandlerClasse:(Class)class_
{
LOGClassFnStart();
NSDebugMLLog(@"associations",@"class_=%@",class_);
TmpLockBeforeDate(associationsLock,[NSDate dateWithTimeIntervalSinceNow:GSLOCK_DELAY_S]);
if (associationsHandlerClasses)
{
if (class_)
[associationsLogsHandlerClasses removeObject:class_];
};
TmpUnlock(associationsLock);
LOGClassFnStop();
};
@end
/*
//====================================================================
@implementation GSWAssociation (GSWAssociationOldFn)
//--------------------------------------------------------------------
// value
-(id)value
{
//OK
GSWContext* context=[[GSWApplication application] context];
id object=[context component];
[self valueInComponent:object];
};
//--------------------------------------------------------------------
// setValue:inComponent:
//OldFn
-(void)setValue:(id)value_
{
//OK
GSWContext* context=[[GSWApplication application] context];
id object=[context component];
[self setValue:(id)value_
inComponent:object];
};
@end
*/
//====================================================================
@implementation GSWAssociation (GSWAssociationA)
//--------------------------------------------------------------------
-(BOOL)isImplementedForComponent:(NSObject*)component_
{
//OK
[self subclassResponsibility:_cmd];
return NO;
};
@end
//====================================================================
@implementation GSWAssociation (GSWAssociationB)
//--------------------------------------------------------------------
-(NSString*)keyPath
{
//OK
[self subclassResponsibility:_cmd];
return nil;
};
//--------------------------------------------------------------------
-(void)logValue:(id)value_
forSet:(BOOL)set_
{
if (debugEnabled)
{
if (associationsLogsHandlerClasses)
{
TmpLockBeforeDate(associationsLock,[NSDate dateWithTimeIntervalSinceNow:GSLOCK_DELAY_S]);
NS_DURING
{
int i=0;
Class _class=Nil;
int _handlerCount=[associationsLogsHandlerClasses count];
NSString* _debugDescription=[self debugDescription];
for(i=0;i<_handlerCount;i++)
{
_class=[associationsLogsHandlerClasses objectAtIndex:i];
if (set_)
[_class logSetValueForDeclarationNamed:declarationName
type:declarationType
bindingNamed:bindingName
associationDescription:_debugDescription
value:value_];
else
[_class logTakeValueForDeclarationNamed:declarationName
type:declarationType
bindingNamed:bindingName
associationDescription:_debugDescription
value:value_];
};
}
NS_HANDLER
{
LOGException(@"%@ (%@)",localException,[localException reason]);
TmpUnlock(associationsLock);
[localException raise];
}
NS_ENDHANDLER;
TmpUnlock(associationsLock);
};
};
};
//--------------------------------------------------------------------
-(void)logTakeValue:(id)value_
{
[self logValue:value_
forSet:NO];
};
//--------------------------------------------------------------------
-(void)logSetValue:(id)value_
{
[self logValue:value_
forSet:YES];
};
//--------------------------------------------------------------------
-(void)logSynchronizeForValue:(id)value_
inComponent:(NSObject*)component_
componentToParent:(BOOL)componentToParent_
{
if (associationsHandlerClasses)
{
TmpLockBeforeDate(associationsLock,[NSDate dateWithTimeIntervalSinceNow:GSLOCK_DELAY_S]);
NS_DURING
{
int i=0;
Class _class=Nil;
int _handlerCount=[associationsLogsHandlerClasses count];
NSString* _debugDescription=[self debugDescription];
for(i=0;i<_handlerCount;i++)
{
_class=[associationsLogsHandlerClasses objectAtIndex:i];
if (componentToParent_)
[_class logSynchronizeComponentToParentForValue:value_
association:self
inComponent:component_];
else
[_class logSynchronizeParentToComponentForValue:value_
association:self
inComponent:component_];
};
}
NS_HANDLER
{
LOGException(@"%@ (%@)",localException,[localException reason]);
TmpUnlock(associationsLock);
[localException raise];
}
NS_ENDHANDLER;
TmpUnlock(associationsLock);
};
};
//--------------------------------------------------------------------
-(void)logSynchronizeComponentToParentForValue:(id)value_
inComponent:(NSObject*)component_
{
[self logSynchronizeForValue:value_
inComponent:component_
componentToParent:YES];
};
//--------------------------------------------------------------------
-(void)logSynchronizeParentToComponentForValue:(id)value_
inComponent:(NSObject*)component_
{
[self logSynchronizeForValue:value_
inComponent:component_
componentToParent:NO];
};
//--------------------------------------------------------------------
-(NSString*)debugDescription
{
//OK
[self subclassResponsibility:_cmd];
return nil;
};
//--------------------------------------------------------------------
-(void)setDebugEnabledForBinding:(NSString*)bindingName_
declarationName:(NSString*)declarationName_
declarationType:(NSString*)declarationType_
{
debugEnabled=YES;
ASSIGN(bindingName,bindingName_);
ASSIGN(declarationName,declarationName_);
ASSIGN(declarationType,declarationType_);
};
//--------------------------------------------------------------------
+(id)valueInObject:(id)object_
forKeyPath:(NSString*)keyPath_
{
id retValue=nil;
#ifdef GDL2
id EONullNull=[EONull null];
#else
id EONullNull=[NSNull null];
#endif
LOGClassFnStart();
NSDebugMLLog(@"associations",@"GSWAssociation: keyPath_=%@ object_=%p",keyPath_,(void*)object_);
if (keyPath_ && object_ && object_!=EONullNull)
{
#if GDL2
NS_DURING
{
retValue=[object_ valueForKeyPath:keyPath_];
}
NS_HANDLER
{
NSLog(@"Attempt to get %@ -%@ raised an exception (%@)",
[object_ class],
keyPath_,
localException);
localException = [localException exceptionByAddingToUserInfoKey:@"Invalid Ivars/Methods"
format:@"-[%@ %@]",
[object_ class],
keyPath_];
[localException raise];
}
NS_ENDHANDLER;
if (retValue==EONullNull)
retValue=nil;
#else
NSMutableArray* keys=[[keyPath_ componentsSeparatedByString:@"."] mutableCopy];
id _part=nil;
Class _handlerClass=Nil;
retValue=object_;
NSAssert(retValue,@"No Component");
while(retValue && [keys count]>0)
{
_part=[keys objectAtIndex:0];
[keys removeObjectAtIndex:0];
if (retValue) {
NSDebugMLLog(@"associations",@"object_get_class_name(retValue object)=%s", object_get_class_name(retValue));
}
NSDebugMLLog(@"associations",@"_part=%@",_part);
NSDebugMLLog(@"associations",@"_part class=%@",NSStringFromClass([_part class]));
if ([_part hasPrefix:@"\""])
{
_part=[_part stringWithoutPrefix:@"\""];
while([keys count]>0)
{
id tmpPart=[keys objectAtIndex:0];
[keys removeObjectAtIndex:0];
if ([tmpPart hasSuffix:@"\""])
{
tmpPart=[tmpPart stringWithoutSuffix:@"\""];
_part=[_part stringByAppendingFormat:@".%@",tmpPart];
break;
}
else
_part=[_part stringByAppendingFormat:@".%@",tmpPart];
}
}
NSDebugMLLog(@"associations",@"_part=%@",_part);
_handlerClass=[associationsHandlerClasses objectForKey:_part];
NSDebugMLLog(@"associations",@"_handlerClass=%@",_handlerClass);
if (_handlerClass)
retValue=[_handlerClass processValueInObject:retValue
forHandler:_part
forKeyPath:keys];
else if ([_part isEqualToString:GSASK_Class])
{
Class _class=Nil;
NSAssert2([keys count]>0,@"No class name for handler %@ in %@",
GSASK_Class,
keyPath_);
_part=[keys objectAtIndex:0];
[keys removeObjectAtIndex:0];
NSDebugMLLog(@"associations",@"_part=%@",_part);
_class=NSClassFromString(_part);
NSAssert3(_class>0,@"No class named %@ for handler %@ in %@",
_part,
GSASK_Class,
keyPath_);
if (_class)
retValue=_class;
else
retValue=nil;
}
else if ([_part isEqualToString:GSASK_Language])
{
NSArray* languages=[[GSWApp _context] languages];
int count=[languages count];
id v=nil;
int i=0;
for(i=0;!v && i<count;i++)
{
id language=[languages objectAtIndex:i];
//MGNEW v=[retValue getIVarNamed:language];
v=[retValue valueForKey:language];
};
retValue=v;
}
else
{
BOOL skipping = NO;
NSDebugMLLog(@"associations",@"call %@ valueForKey:%@",
[retValue class],
_part);
NS_DURING
{
//MGNEW retValue=[retValue getIVarNamed:_part];
retValue=[retValue valueForKey:_part];
}
NS_HANDLER
{
NSLog(@"Attempt to get %@ -%@ raised an exception (%@)",
[retValue class],
_part,
localException);
localException = [localException exceptionByAddingToUserInfoKey:@"Invalid Ivars/Methods" format:@"-[%@ %@]",[retValue class],_part];
[localException raise];
}
NS_ENDHANDLER;
};
if (retValue==EONullNull)
retValue=nil;
};
#endif
};
if (retValue)
{
NSDebugMLLog(@"associations",@"retValue=%@",retValue);
}
else
{
NSDebugMLLog(@"associations",@"retValue=nil");
}
LOGClassFnStop();
return retValue;
};
//--------------------------------------------------------------------
+(void)setValue:(id)value_
inObject:(id)object_
forKeyPath:(NSString*)keyPath_
{
LOGClassFnStart();
NSDebugMLLog(@"associations",@"GSWAssociation: setValue:%@",value_);
NSDebugMLLog(@"associations",@"value_ class:%@",[value_ class]);
NSDebugMLLog(@"associations",@"value_ String class:%@",NSStringFromClass([value_ class]));
NSDebugMLLog(@"associations",@"object_ String class:%@",NSStringFromClass([object_ class]));
NSDebugMLLog(@"associations",@"GSWAssociation: keyPath_:%@",keyPath_);
if (keyPath_)
{
#if GDL2
[object_ takeValue:value_
forKeyPath:keyPath_];
#else
NSMutableArray* keys=[[keyPath_ componentsSeparatedByString:@"."] mutableCopy];
id _part=nil;
id _object=object_;
Class _handlerClass=Nil;
NSAssert(_object,@"No Object");
while(_object && [keys count]>0)
{
_part=[keys objectAtIndex:0];
[keys removeObjectAtIndex:0];
NSDebugMLLog(@"associations",@"_part=%@",_part);
NSDebugMLLog(@"associations",@"_part class=%@",NSStringFromClass([_part class]));
if ([_part hasPrefix:@"\""])
{
_part=[_part stringWithoutPrefix:@"\""];
while([keys count]>0)
{
id tmpPart=[keys objectAtIndex:0];
[keys removeObjectAtIndex:0];
if ([tmpPart hasSuffix:@"\""])
{
tmpPart=[tmpPart stringWithoutSuffix:@"\""];
_part=[_part stringByAppendingFormat:@".%@",tmpPart];
break;
}
else
_part=[_part stringByAppendingFormat:@".%@",tmpPart];
}
}
NSDebugMLLog(@"associations",@"_part=%@",_part);
_handlerClass=[associationsHandlerClasses objectForKey:_part];
NSDebugMLLog(@"associations",@"_handlerClass=%@",_handlerClass);
if (_handlerClass)
{
_object=[_handlerClass processSetValue:value_
inObject:_object
forHandler:_part
forKeyPath:keys];
}
else
{
if ([keys count]>0)
{
if ([_part isEqualToString:GSASK_Class])
{
Class _class=Nil;
NSAssert2([keys count]>0,@"No class name for handler %@ in %@",
GSASK_Class,
keyPath_);
_part=[keys objectAtIndex:0];
[keys removeObjectAtIndex:0];
NSDebugMLLog(@"associations",@"_part=%@",_part);
_class=NSClassFromString(_part);
NSAssert3(_class>0,@"No class named %@ for handler %@ in %@",
_part,
GSASK_Class,
keyPath_);
if (_class)
_object=_class;
else
_object=nil;
}
else {
//MGNEW _object=[_object getIVarNamed:_part];
_object=[_object valueForKey:_part];//MGNEW
}
}
else
{
GSWLogAssertGood(_object);
//MGNEW [_object setIVarNamed:_part
// withValue:value_];
[_object takeValue:value_
forKey:_part];//MGNEW
#ifdef GDL2
NSDebugMLLog(@"associations",@"object_ class=%@",[object_ class]);
NSDebugMLLog(@"associations",@"_object class=%@",[_object class]);
// Turbocat
if (_object && [_object isKindOfClass:[GSWComponent class]]) {
NSException* _exp = [_object validateValue:&value_ forKey:_part];
if (_exp) {
NSException* _exception=nil;
_exception=[NSException exceptionWithName:@"EOValidationException"
reason:[_exp reason]
userInfo:[NSDictionary
dictionaryWithObjectsAndKeys:
(value_ ? value_ : @"nil"),@"EOValidatedObjectUserInfoKey",
keyPath_,@"EOValidatedPropertyUserInfoKey",
nil,nil]];
[object_ validationFailedWithException:_exception
value:value_
keyPath:keyPath_];
}
}
#endif
_object=nil;
};
};
};
#endif
}
else
{
NSDebugMLLog(@"associations",@"GSWAssociation: setValue:%@ : NoKeyPath",value_);
};
LOGClassFnStop();
};
@end
//===================================================================================
@implementation NSDictionary (GSWAssociation)
-(BOOL)isAssociationDebugEnabledInComponent:(NSObject*)component_
{
BOOL _debug=NO;
GSWAssociation* _debugAssociation=[self objectForKey:@"GSWDebug"];
if (_debugAssociation)
{
id _value=[_debugAssociation valueInObject:component_];
_debug=boolValueWithDefaultFor(_value,NO);
};
return _debug;
};
-(void)associationsSetDebugEnabled
{
NSEnumerator* enumerator=nil;
id _key=nil;
id _asociation=nil;
LOGObjectFnStart();
enumerator = [self keyEnumerator];
while ((_key = [enumerator nextObject]))
{
NSDebugMLLog(@"associations",@"_key=%@",_key);
_asociation=[self objectForKey:_key];
[_asociation setDebugEnabledForBinding:@""
declarationName:_key
declarationType:@""]; //TODO
};
LOGObjectFnStop();
};
-(void)associationsSetValuesFromObject:(id)from_
inObject:(id)to_
{
NSEnumerator *enumerator = nil;
id _key=nil;
id _varValue=nil;
id _var=nil;
LOGObjectFnStart();
enumerator = [self keyEnumerator];
while ((_key = [enumerator nextObject]))
{
NSDebugMLLog(@"associations",@"_key=%@",_key);
_var=[self objectForKey:_key];
NSDebugMLLog(@"associations",@"_var=%@",_var);
_varValue=[_var valueInComponent:from_];
NSDebugMLLog(@"associations",@"_varValue=%@",_varValue);
[_key setValue:_varValue
inComponent:to_];
};
LOGObjectFnStop();
};
//--------------------------------------------------------------------
-(NSDictionary*)associationsWithoutPrefix:(NSString*)prefix_
removeFrom:(NSMutableDictionary*)removeFrom_
{
NSMutableDictionary* _newAssociation=nil;
NSEnumerator *enumerator = nil;
id _key=nil;
id _varKey=nil;
id _varKeyAssociation=nil;
id _value=nil;
LOGObjectFnStart();
_newAssociation=[NSMutableDictionary dictionary];
enumerator = [self keyEnumerator];
while ((_key = [enumerator nextObject]))
{
NSDebugMLLog(@"associations",@"_key=%@",_key);
if ([_key hasPrefix:prefix_])
{
[removeFrom_ removeObjectForKey:_key];
_value=[self objectForKey:_key];
NSDebugMLLog(@"associations",@"_value=%@",_value);
_varKey=[_key stringWithoutPrefix:prefix_];
NSDebugMLLog(@"associations",@"_varKey=%@",_varKey);
_varKeyAssociation=[GSWAssociation associationWithKeyPath:_varKey];
NSDebugMLLog(@"associations",@"_varKeyAssociation=%@",_varKeyAssociation);
[_newAssociation setObject:_value
forKey:_varKeyAssociation];
};
};
_newAssociation=[NSDictionary dictionaryWithDictionary:_newAssociation];
LOGObjectFnStop();
return _newAssociation;
};
//--------------------------------------------------------------------
-(NSDictionary*)dictionaryByReplacingStringsWithAssociations
{
NSMutableDictionary* _newDictionary=[NSMutableDictionary dictionary];
NSEnumerator* _enum=[self keyEnumerator];
id _key=nil;
id _value=nil;
id _newValue=nil;
while ((_key=[_enum nextObject]))
{
_value=[self objectForKey:_key];
NSDebugMLog(@"_key=%@ _value=%@",_key,_value);
if ([_value isKindOfClass:[NSString class]])
{
_newValue=[GSWAssociation associationFromString:_value];
NSAssert(_newValue,@"Nil value");
}
else if ([_value isKindOfClass:[NSArray class]])
{
_newValue=[_value arrayByReplacingStringsWithAssociations];
NSAssert(_newValue,@"Nil value");
}
else if ([_value isKindOfClass:[NSDictionary class]])
{
_newValue=[_value dictionaryByReplacingStringsWithAssociations];
NSAssert(_newValue,@"Nil value");
}
else
_newValue=_value;
[_newDictionary setObject:_newValue
forKey:_key];
};
return [NSDictionary dictionaryWithDictionary:_newDictionary];
};
@end
//===================================================================================
@implementation NSArray (GSWAssociation)
-(NSArray*)arrayByReplacingStringsWithAssociations
{
NSMutableArray* _newArray=[NSMutableArray array];
int _count=[self count];
int i=0;
id _value=nil;
id _newValue=nil;
for(i=0;i<_count;i++)
{
_value=[self objectAtIndex:i];
NSDebugMLog(@"i=%d _value=%@",i,_value);
if ([_value isKindOfClass:[NSString class]])
{
_newValue=[GSWAssociation associationFromString:_value];
}
else if ([_value isKindOfClass:[NSArray class]])
{
_newValue=[_value arrayByReplacingStringsWithAssociations];
}
else if ([_value isKindOfClass:[NSDictionary class]])
{
_newValue=[_value dictionaryByReplacingStringsWithAssociations];
}
else
_newValue=_value;
[_newArray addObject:_newValue];
};
return [NSArray arrayWithArray:_newArray];
};
@end