hey, you didn't mention my ambiguity resolution hack
(IValidatorWithBehavior). or did it not work out? this seemed like the
best thing to me if it works.
Eelco Hillenius wrote:
>
> We have a bit of a stalemate currently in how we'll support validators
> that are or contribute behaviors.
>
> First, why would we want such behaviors? It is to enable validators to
> influence what is rendered so that they can e.g. set a maxlength
> attribute, add client side javascript validation, or even add ajax
> validation (or a combination of these).
>
> For example:
>
> private static class MaxLengthValidator extends
> StringValidator.MaximumLengthValidator
> implements
> IBehaviorProvider
> {
> public MaxLengthValidator(int maximum)
> {
> super(maximum);
> }
>
> public IBehavior newValidationBehavior(Component component)
> {
> if (component instanceof AbstractTextComponent)
> {
> return new SimpleAttributeModifier("maxlength",
> String.valueOf(getMaximum()));
> }
> return null;
> }
> }
>
> The current implementation is based on interface IBehaviorProvider:
>
> /**
> * Validator that provides a behavior, e.g. for rendering client-side or
> ajax
> * validation. This interface can be implemented by either
> * [EMAIL PROTECTED] IValidator validators} or [EMAIL PROTECTED]
> IFormValidator form
> validators}.
> */
> public interface IBehaviorProvider extends IClusterable
> {
> /**
> * Gets behavior for validation. This method is called right after the
> * validator is added to a form or form component. The resulting
> behavior
> * will be added to the component. Note that after the behavior is
> added,
> it
> * will just lead its own life; this method will not be invoked anymore.
> *
> * @param component
> * component currently using the validator
> * @return The behavior, which can be used for rendering e.g. javascript
> or
> * ajax validation. If this returns null, it will be ignored.
> */
> IBehavior newValidationBehavior(Component component);
> }
>
> which is an optional interface your validators can implement if they
> want to contribute such behaviors.
>
> Now Igor in particular has a problem with this solution as he likes
> the alternative (which I actually implemented at first, but didn't
> commit) where you can simply code classes that are both a validator
> and a behavior (implement IValidator or IFormValidator and IBehavior).
>
> The technical issue with that is that we have an add method for both,
> while they have a different hierarchy, so unless you do a hard cast,
> it's not going to work. And even if you do a hard cast, behaviors and
> validators are currently stored in their own structures, so either the
> add methods would have to be aware that a behavior can also be a
> validator (detail: validators currently are only known by form
> components, so add(IBehavior) would have to do some instanceof
> checking on itself to get this working) and that a validator can be a
> behavior in the add(I(Form)Validator) method.
>
> A way to fix this is to create a common interface (in my
> implementation I called this IComponentFacet) for IBehavior and
> IValidator and have one add method. In the mechanism I implemented,
> facets were stored in the same structure (so the validators field in
> FormComponent was removed) and it worked with a lookup method like
> getFacets(Class).
>
> The problem with this though is that once we start thinking in this
> direction, it opens up a whole new range of questions. For instance,
> what happens when people add validators to non-form components? Is
> 'detachable' or 'onBefore/AfterRender' really only something for
> behaviors? What kind of mixing and matching can we expect people to
> try in the future? I guess my largest problem is that I don't have a
> great feeling about this mixing conceptually. I think in a future
> version of Wicket, we might improve components by decoupling parts of
> it so that you can assemble the parts you need. If and only if that
> would really be worth the increased complexity of the API that comes
> with such a change. However, I'm afraid that by supporting a kind-of
> mixin like a combined validator and behavior is a step in that
> direction, but it's too soon, half baked (like Jonathan stated on IRC,
> we probably first need a full fledged event system in components if we
> want to support components by composition).
>
> The elegance of the current solution is that imho it doesn't have any
> conceptual blur. Validators are still validators, but by implementing
> IBehaviorProvider they can additionally *contribute* a behavior, which
> is very different from *being* (IS-A) a behavior at the same time. It
> is easy to implement (it's in svn right now, and I'm not worried for
> one second this addition is limiting the way we can grow our API as
> long as we keep this simple). Nice about the current solution is also
> that it is easy to let your validator return different behaviors, e.g.
> depending on the (type of) component it is coupled to. You can achieve
> the same by using delegation in the validator/behavior you'd implement
> otherwise, but imo, that's much less elegant and basically forces you
> to either implement this pattern over and over again, or extend a base
> class which limits your options. Not to mention that in the IS-A
> scenario you'd have to be aware that if something can be an attribute
> modifier or/ and an ajax behavior, you'd have to implement interface
> IBehaviorListener or be ok with implementing an abstract ajax behavior
> even if you would just need the attribute modifier for one occassion.
>
> I guess my point is made. I'll back off for a bit and see what other
> people have to say about this. Anyone's opinions are welcome, and core
> developers, please contribute so that we can make this decision in
> consensus.
>
> Cheers,
>
> Eelco
>
>
--
View this message in context:
http://www.nabble.com/poll%3A-validators-and-behaviors-combined...-contribute-or-IS-A--tf3727027.html#a10437839
Sent from the Wicket - Dev mailing list archive at Nabble.com.