Dmitri,

> you solution is very interesting, but I am not absolutely happy with the
> fact,
> that control is specified not only in struts-config.xml but in source code
> as well (map definition).

I don't think my solution takes control away from struts-config, it only
gives the action more control over how it handles things directed towards
it.

> Even application properties play here an important
> role.

I don't understand what you mean by application properties playing a role.
How so?

More comments in-line below....

> I have tried to use your ideas and produced very simple solution which
would
> satisfy
> both buttons and images needs.
>
> struts-config.xml
> =================
>
>     <action    path="/test"
>                type="org.apache.struts.actions.MultiSubmitAction"
>                name="testForm"
>               scope="request"
>               input="/test.jsp">
>       <forward name="add.x"         path="/add.do"/>
>       <forward name="delete.x"      path="/delete.do"/>
>     </action>

Definitely an interesting indirection mapping scheme... but that means that
for
every form there is an action mapping, and another action class and mapping
for each button on the form.  struts-config.xml will already be huge in our
application of hundreds of forms, so having a single mapping per form is
important not only to keep the config smaller, but to keep it clearer.

Your solution does accomplish the multi-button issue by naming each button
uniquely.  I feel more comfortable with each button having the same name,
but I suppose that is a matter of preference (and as such is accounted for
in the two base classes I'm proposing).  In your case you'd have to be
careful not to have a property of your form bean with the same name as any
of the button names - in my design you'd just have to make sure not to have
one form bean property (i.e. "action").

> MultiSubmitAction.java
> ======================
>
> public class MultiSubmitAction extends Action {
>
>     public ActionForward perform(ActionMapping mapping,
> ActionForm form,
> HttpServletRequest request,
> HttpServletResponse response)
> throws IOException, ServletException {
>
>         String forwards[] = mapping.findForwards();
>
>         for (int i = 0; i < forwards.length; i++) {
>             if (request.getParameter(forwards[i]) != null) {
>                 // Return the required ActionForward instance
>                 return mapping.findForward(forwards[i]);
>             }
>         }
>
>         // Go back to input (any other ideas ?)
>         return new ActionForward(mapping.getInput());

Ideas - How about returning ActionErrors if the mapping isn't found?  Or I
personally would throw a JspException since this is truly a situation that
cannot be handled wisely by the action in all cases and represents a
situation that should not happen.

> Some considerations:
>
> If you never intend to use images, then you can omit ".x" suffix.

In your design, struts-config.xml will have to be modified if a designer
switches between using a graphic button and text buttons by adding or
removing the ".x", or as in your example, name text buttons with ".x" on
them - which I don't prefer.  My goals are to make the designers life as
easy and straightforward as possible, and having text buttons named ".x"
just doesn't make a lot of sense without knowing whats going on under the
hood.  A designer shouldn't have to care what is going on under the hood.

> If somebody wants to have all methods stored in one file he can subclass
> DispatchAction
> and play with parameter property:
>
>     <action    path="/add"
>                type="org.apache.struts.webapp.example.AddDeleteAction"
>                name="testForm"
>               parameter="add"
>               scope="request"
>               input="/test.jsp">
>     </action>
>
>     <action    path="/delete"
>                type="org.apache.struts.webapp.example.AddDeleteAction"
>                name="testForm"
>               parameter="delete"
>               scope="request"
>               input="/test.jsp">
>     </action>

I don't think using DispatchAction as you suggest will work.  What it
would do in the "add" case is this:

- call request.getParameter("add") - what would that return in your case?
The text of the button.

- Then it would attempt to look up a method named the text of the button.
This is not a very plausible scenario because the button labels need to be
separated from the action, and not considered (directly), and of course its
unlikely you'd name your methods appropriately, since you couldn't have a
method named "Add Record" but that is a very likely button text.

Maybe I'm missing a piece of your design here, but the parameter value used
in DispatchAction uses a level of indirection that I don't see being
accounted for here.

> Instead of 'misusing' mappings it might be possible to introduce some
> additional tag
> to action config:
>
>       <dispatch property="delete.x" path="/delete.do"/>
> or
>       <dispatch property="delete.x" method="delete"/>

I think this kind of mapping puts unnecessary stuff in an already cluttered
struts-config.xml file.  Having a subclass of my LookupDispatchAction to
control what happens for each button seems the right place to put that
control - its not something that is really a run-time configuration need,
and even if you wanted to play wild dynamic games over the button key/method
mappings, you could take advantage of the mapping, request, or form objects
being passed to my getKeys or getKeyMethodMap methods (I put them there for
just this very reason, although I can't imagine a scenario yet where that
would be needed).

In summary, I still prefer my design for these reasons:

- cleaner struts-config, less action classes (less code means less code to
test, less room for error, XP says "less code is better")

- no burden on designers to deal with struts-config or name text buttons
with ".x" extensions (designers are our friends and the easier we make it on
them the better - Struts tags are probably confusing enough for them! :)

- allowing the action class control over what it should (IMO) control

I'd love to hear counter arguments and discussion on this issue.  I would be
ecstatic if some form of this can make it in the upcoming release.

    Erik




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

Reply via email to