Hello,

Johann and I were having a conversation here:

https://github.com/wocommunity/wonder/commit/6665a308b630557ce6639e75ec4a49d0d86f79f4

about the behaviour of ERXGenericRecord.validateValueForKey(Object value, 
String key). The short version is that Johann noticed a bug in the way 
_validateValueForKey() was being called, fixed it in 6665a308, and then fixed 
it some more in 92d51ff3.

The longer version is that what’s going on in 
ERXGenericRecord.validateValueForKey() in the try block is:

1. super.validateValueForKey(value, key) is called, and is assigned to the 
‘result' local variable.
2. ERXEntityClassDescription.validateObjectWithUserInfo(this, value, 
"validateForKey." + key, key) is called. Note that the argument there is 
‘value’.
3. _validateValueForKey(result, key) is called and assigned to ‘result’.

There are a couple of things to discuss here, and I’ll just paste in the part 
of the method we’re talking about.

try {
        result = super.validateValueForKey(value, key);
        EOClassDescription cd = classDescription();
        if (cd instanceof ERXEntityClassDescription) {
                ((ERXEntityClassDescription) 
cd).validateObjectWithUserInfo(this, value, "validateForKey." + key, key);
        }
        result = _validateValueForKey(result, key);
}

1. There’s a kind of “cascade” of validation going on, with each successive 
validation call potentially modifying ‘result’ further. Ignoring step 2 above 
for a moment, each of super.validateValueForKey() and then any partial entity’s 
implementation of _validateValueForKey() will (potentially) successively modify 
result. While this might sound odd, it’s only an issue if two different classes 
implement the same validateFoo() method for some key ‘foo’, which presumably 
wouldn’t normally happen. Partial entities, for example, should probably by 
convention only be implementing validation methods for keys they add to the 
entity. In any case, the alternative is “last modification wins”, which is the 
bug Johann was correcting—_validateValueForKey() was previously modifying the 
original ‘value’ and being allowed to return that, hence trumping any other 
modifications. I just wondered whether it was worth sanity checking the idea 
here first, because Johann has pointed out that we probably need to modify 
_validateValueForKey(Object, String) to do the same thing, as currently that 
method is “last modification wins”:

@Override
protected Object _validateValueForKey(Object value, String key) throws 
ValidationException {
        Object result = value;
        for (ERXPartial partial : _partials()) {
                result = partial.validateValueForKey(value, key);
        }
        return result;
}

Surely that should be result = partial.validateValueForKey(result, key), or 
else a modification by partial P1 gets wiped out by a partial P2 further down 
the list that doesn’t want to do anything with that key (and hence returns 
‘value’ unmodified). Does anyone disagree?

2. I don’t know what ERXEntityClassDescription.validateObjectWithUserInfo() 
does, but currently (see above) it’s also being passed the original ‘value’. 
Should this method also be passed ‘result’ at this point?


-- 
Paul Hoadley
http://logicsquad.net/



 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to