Keyton,
Good thoughts. Proves how hard it is to write tutorials. :-)
On Sat, 12 May 2001, A. Keyton Weissinger wrote:
> > 1) Properties are expected to remain consistent. This means that:
> >
> > - no user code should call a setXXX() accessor of a tag handler
> Should this not be amended to be the following?
> - no user code should call a setXXX() accessor corresponding to a tag
> attribute.
> It seems to me that I may want some setters on my tag that are outside the
> attribute mechanism.
> For example, if I have:
> <ora:displayContents>
> <ora:getContents/>
> </ora:displayContents>
> It might be nice to have a setContent() method in the parent tag that
> does not affect a tag attribute.
> This needs more thought, but I think you see what I mean....
Fair enough. As an aside, I tend to personally avoid, in tag handlers,
using properties gratuitously for data other than attributes. (Of course,
there are valid reasons for doing so; I just avoid it when there's no
particular reason for doing so.)
Having unrelated properties can limit opportunities for code reuse.
Suppose I want to subclass your handler for "displayContents"; I wouldn't
be able to give my new handler an attribute called "contents." If
"contents" is a documented JavaBean property of the class and meant to be
used as such, that's fine. If it's, instead, just an implementation
detail, then it's arguably exposing more than it should.
> > a) Suppose you have a tag that accepts some sort of expression that you
> > need to resolve, e.g.:
> >
> > <show value="$my-expression$"/>
> >
> > "$my-expression$" should be stored by setValue() and evaluated in
> > doStartTag(). For the behavior that's almost always desired, it
> > shoule NOT be evaluated in setValue().
> I disagree somewhat with this. If you have some runtime validation of
> attributes values occurring, you may want this to happen in the
> setters -- to short circuit the process. Why wait for
> doStartTag()? This would require evaluation, but not any further
> processing. THoughts?
Right, the validation is okay; believe it or not, I thought I had included
something about "checking" attributes, but I guess I didn't. The key is
that it shouldn't be *resolved* in the accessor.
In other words, checking "$my-expression$" to make sure its syntax is
valid is perfectly fine, and that check is most efficiently handled in the
setValue() method. But storing the object to which it resolves shouldn't
(in the typical case) be done until doStartTag(), because the object to
which the expression refers might change between the time that the
property is set (perhaps far in the distant past) and the moment that the
tag handler is actually invoked.
E.g., in
<defineAttribute scope="page" name="a" value="b"/>
<readAttribute scope="page" name="a"/>
<defineAttribute scope="page" name="a" value="c"/>
<readAttribute scope="page" name="a"/>
readAttributeHandler.setA() need not be called more than once to handle
this fragment, so accessing the pageContext in the accesor will miss
changes to the object that's stored under the key 'a'.
Shawn