On Wed, 16 Jul 2003, Ranjangaonkar, Vaibhav (HQP) wrote:

> Date: Wed, 16 Jul 2003 12:56:09 -0700
> From: "Ranjangaonkar, Vaibhav (HQP)" <[EMAIL PROTECTED]>
> Reply-To: Struts Developers List <[EMAIL PROTECTED]>
> To: Struts Developers List <[EMAIL PROTECTED]>
> Subject: RE: DynaActionForm.getMap() change
>
> My 0.2 cents -
> I think, idea to provide getMap() method is great !
> Yes, to solve the performance problem, I think, then
> We will have to keep track when underlying map has
> Changed. Then, create unmodifiable map only if it changed
> Since the last time...
>

The current implementation already has getMap() -- the problem is that it
returns the real HashMap that is internally used to store property values,
which exposes those values to being modified by means other than through
the DynaActionForm methods.

I don't like the performance impact of creating a new wrapper instance on
every call to getMap(), however -- that can happen lots of times in a
page.  It's probably possible to create the wrapper once and then cache it
(to reduce the impact somewhat), but it is still a spurious object
creation.

> Actually, this is a common java idiom, I think. Whenever
> We need to expose a collection from a class, we should
> return unmodifiable variant of it so that encapsulation
> doesn't break, but then, we have performance issue, as
> David said...
>
> Thanks.

The reason to think about doing it is usability, which sometimes needs to
win out over O-O purity :-).

All of the Struts tags, because they use commons-beanutils under the
covers, treat DynaBean beans and standard JavaBeans identically -- the
internal implementation knows exactly what to do.  So you can say things
like:

  <html:bean:write name="customer" property="firstName"/>

Now, assume you've got a page author that wants to switch and use JSTL EL
expressions instead.  Their natural first inclination is going to be to
write:

  <c:out value="${customer.firstName}"/>

which will work fine for a standard JavaBean, but not fine for a DynaBean.
If it *happens* to be a DynaActionForm, you can work around this by
saying:

  <c:out value="${customer.map.firstName}"/>

because we added getMap() to DynaActionForm.  This is really confusing to
newcomers, and would be unnecessary if we went to DynaActionForm
implementing Map.  Then, the user's initial guess at how to write the
expression would have been correct.

Given that JSP 2.0 makes EL expressions available everywhere in a page, so
that you'd be able to write just this instead:

  ${customer.firstName}

then I think the usability issue is strong enough that we should look at
making DynaActionForm implement Map so that it plays nicely with all EL
expressions.

SIDE NOTE:  In JavaServer Faces, the APIs let you customize a thing called
the PropertyResolver, which is the piece of code that interprets the "."
or "[]" operators in an EL expression.  In the most recent release of the
Struts-Faces integration library, I took of advantage of this and
implemented support for DynaBeans -- but that only works for value
reference expressions in Faces components, not in other uses of EL in the
page.

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to