/*!
@header ECXMLControlReferenceRule
@abstract Module of Encore
@availability OS X, GNUstep
@copyright 2004, 2005, 2006 Oliver Langer
Author: Oliver Langer
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-------------------------------------------------------------------------
Modification history
10.02.06 ola initial version
22.08.06 ola license changed
-------------------------------------------------------------------------
*/
#include
#include
#include
#include
@implementation ECXMLControlReferenceRule
- init {
self = [super init];
self->setterLookupUtil = [[ECXMLControlSetterLookupUtil alloc] init];
return self;
}
- (void) dealloc {
[self->setterLookupUtil release];
[super dealloc];
}
- (BOOL) mayActOn: (ECXMLControlContext *) aContext {
return [[[aContext event] eventId]
isEqual: [ECXMLControlEvent eventId_addAttribute]];
}
- addObject: (id) anObject withRefId: (NSString *) aRefId
usingDictionary: (NSMutableDictionary *) aDictionary {
NSMutableDictionary *references;
references = (NSMutableDictionary *)
[aDictionary objectForKey: @"__ECXMLControlReferenceRule"];
if( nil == references ) {
references = [[NSMutableDictionary alloc] init];
[aDictionary setObject: references forKey: @"__ECXMLControlReferenceRule"];
}
if( nil != [references objectForKey: aRefId] ) {
[[[ECIllegalStateException alloc]
initWithIllegalStateInfo:
[NSString stringWithFormat: @"ECXMLControlReferenceRule::addObject: "\
"Identifier id=%@ has already been defined!", aRefId]]
raise];
}
[references setObject: anObject forKey: aRefId];
return self;
}
- (BOOL) actOn: (ECXMLControlContext *) aContext {
id userObject;
NSString *attributeName;
NSArray *splits;
BOOL ignoreSubsequentCalls = NO;
userObject = [[aContext state] userObjectAtTopPosition];
if( nil == userObject ) {
return NO;
}
EC_AUTORELEASEPOOL_BEGIN
/**
* check wether the current attribute equals "id" or ends with
* "-idref"
*/
attributeName = [[aContext event] attributeName];
if( NSOrderedSame == [attributeName
caseInsensitiveCompare:@"id"] ) {
[self
addObject: userObject
withRefId: [[aContext event] attributeValue]
usingDictionary: [[aContext state] globalRuleData]];
ignoreSubsequentCalls = YES;
} else {
splits = [attributeName splitStringUsingDelimiter: @"-"];
if( 1 < [splits count] ) {
if( [[splits objectAtIndex: [splits count]-1]
caseInsensitiveCompare: @"id-ref"] ) {
NSString *methodName;
if( 7 < [attributeName length] ) {
methodName = [attributeName
substringToIndex: [attributeName length]-6];
if( nil != methodName ) {
if( 0 < [methodName length] ) {
[self setReferenceToObject: userObject
objectIdReference: [[aContext event] attributeValue]
usingMethod: methodName
usingDictionary: [[aContext state] globalRuleData]];
ignoreSubsequentCalls=YES;
}
}
}
}
}
}
EC_AUTORELEASEPOOL_END
return ignoreSubsequentCalls;
}
- setReferenceToObject: (id) anObject
objectIdReference: (NSString *) idName
usingMethod: (NSString *) methodName
usingDictionary: (NSMutableDictionary *) aDictionary {
id objectToSet;
NSMutableDictionary *references;
SEL methodToCall;
references = (NSMutableDictionary *)
[aDictionary objectForKey: @"__ECXMLControlReferenceRule"];
if( nil == references ) {
[[[ECIllegalStateException alloc]
initWithIllegalStateInfo:
[NSString stringWithFormat: @"ECXMLControlReferenceRule::"\
"setReferenceToObject: Identifier id=%@ unknown!", idName]]
raise];
}
objectToSet = [references objectForKey: idName];
if( nil == objectToSet ) {
[[[ECIllegalStateException alloc]
initWithIllegalStateInfo:
[NSString stringWithFormat: @"ECXMLControlReferenceRule::"\
"setReferenceToObject: Identifier id=%@ unknown!", idName]]
raise];
}
/* lookup method: */
methodToCall = [self->setterLookupUtil
lookupMethodForAttributeName: methodName
ofObject: anObject];
if( NULL != methodToCall ) {
[anObject
performSelector: methodToCall
withObject: objectToSet];
}
return self;
}
@end