You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Ted Husted <hu...@apache.org> on 2001/11/24 16:53:54 UTC

Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Erik Hatcher wrote:
> I believe I might have made this class a little too feature-rich and perhaps
> it should be broken into two base classes - one to dispatch via reflection
> to a Map specified mapping between key and method, and another to do the
> dispatching to an enhanced perform method taking the key.  With two separate
> base classes the getKeys, getKeyMethodMap and perform could all be made
> abstract and remove some likely usage confusion.

I think having two base classes here is a good idea. Here's a first
blush at a separate LookupAction that doesn't use the reflection
techniques from DispatchAction.

It's possible that DispatchAction should be refactored so that invoking
the method is separated from determining the method name. This way a
LookupDispatchAction, and others, could determine the method name by
whatever means they like, and then pass that back.

The idea being that the part in DispatchAction below 

"// Identify the method object to be dispatched to"

could be moved into another method that would finish up, like

    public ActionForward dispatch(ActionMapping mapping,
				 ActionForm form,
				 HttpServletRequest request,
				 HttpServletResponse response,
				 String name)

and the current DispatchAction (or any subclasses) would end with

return (dispatch(mapping,form,request,response,name));

eanwhile, I'm working on adding multibutton submits to "struts-simple"
(which really needs to be renamed), to demonstrate the various
techniques people use, which include

1) Conventional Javascript
2) Javascript via a tag
3) Lookup key from label (annexed)
4) Lookup key from list (not covered in this thread)
5) Lookup key and dispatch
6) Relay to local forward (my personal favorite)

I'm glad this thread came up. I orginally steered clear of
DispatchAction, since it seemed like that the "other" performs would
share a lot of error handling code. I have finally realized that it is
trivial to factor the common code into local methods (keeping everything
on the stack), so that the "other" performs (nomenclature, anyone?)
could really just differ by which business logic method they call.   

It also occurs to me that if you wanted to handle something in another
Action, the "other" perform could just return a forwarding to another
Action. So, you can mix and match the "many" versus "few" Action
strategies as needed.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
----- Original Message -----
From: "Ted Husted" <hu...@apache.org>
> I obviously don't understand the use-case well enough to have a
> reasonable opinion. Needing the keys passed as parameter confuses me,
> since the class already has all that information. Why muddy the
> signature and tell it something it already knows? Everything is
> happening within the same object. Using the original example, the
> parameter "action" is still going to be set to the button's label, and
> any method of the class can look that up whenever they want.

The DispatchKeyAction 'perform' will lookup the appropriate key, and then
dispatch to a method in the subclass.  The subclass 'perform' method won't
know which key was used.  An action should not be using the buttons label
for anything whatsoever - that breaks MVC in a bad way.  Why should the
subclass lookup the key again if it needs it?  What does it hurt to pass the
key to the reflected method?

I envision in our particular application the need to dispatch to several
methods as a form could have several buttons on it to act on the data on the
form.  Some of those actions may not vary much, but having the knowledge of
which button was pressed would be needed to vary the logic to some degree.
It just adds flexibility so that some buttons could map to different
methods, and some to the same method.  Why limit this flexibility when its
easy enough to pass the key parameter also?

    Erik



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Ted Husted <hu...@apache.org>.
Erik Hatcher wrote:
> Oops, sorry.... got it.  I still am lobbying for 'key' to be included in the
> method invoked by DispatchKeyAction.  Pretty please?

I obviously don't understand the use-case well enough to have a
reasonable opinion. Needing the keys passed as parameter confuses me,
since the class already has all that information. Why muddy the
signature and tell it something it already knows? Everything is
happening within the same object. Using the original example, the
parameter "action" is still going to be set to the button's label, and
any method of the class can look that up whenever they want.

-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
----- Original Message -----
From: "Ted Husted" <hu...@apache.org>
> Personally, I would then consider the keys a form of input and make them
> part of the ActionForm.

But then we are back to having the Action have a whole bunch of 'if'
statements for each key.  Sure, a new ActionForm base-class would be handy
to take care of the key lookup, but it doesn't solve the "dispatching"
problem.

The button indicates which "action" to perform, and having the Action class
handle it seems appropriate.  Even with an enhanced ActionForm it would
require coding in Action also.  Why not do it all in a smart Action base
class?

> > What do you mean by "annexed"?  I don't see it anywhere in CVS?
>
> I meant attached.

Oops, sorry.... got it.  I still am lobbying for 'key' to be included in the
method invoked by DispatchKeyAction.  Pretty please?

    Erik



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Ted Husted <hu...@apache.org>.
Erik Hatcher wrote:
> No its not.  What if I want to map several keys to a single method?  That is
> perfectly legitimate use-case where only one minor thing needs to change
> between different key values.

Personally, I would then consider the keys a form of input and make them
part of the ActionForm. 


> What do you mean by "annexed"?  I don't see it anywhere in CVS?

I meant attached.

I haven't a test for the DispatchAction handy, and really can't commit
it without one. Should work though.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
From: "Ted Husted" <hu...@apache.org>
> With DispatchKeyAction, the key is used to call the method itself and
> does not need to be passed. Since reflection is being used, the key is
> implicit in the name of the method invoked.

No its not.  What if I want to map several keys to a single method?  That is
perfectly legitimate use-case where only one minor thing needs to change
between different key values.

So I would like to keep the key being passed to the reflected methods.

> In order to pass a parameter, it has to come from somewhere. Everything
> that perform "knows" is in the original signature, where any reflected
> method can get it.

Not the key though, not directly.  The key should be passed to the reflected
method.

> Actions often need to pull properites and parameters out of the request
> and mappings. But this is best handled by other utility methods in the
> class, that each reflective method could call.

Agreed.  But, again, not the key.  DispatchKeyAction's smarts are in
determining the key.  The reflected methods should not be required to look
it up again.

> I've annexed a DispatchAction with the initial refactoring I mentioned.

What do you mean by "annexed"?  I don't see it anywhere in CVS?

> The idea is that you could start by extending this, overriding perform
> with your own method-name discovery routine, and then call
>
> return dispatchMethod(mapping,form,request,response,name);

But I want "key" also!  :)

Plain ol' DispatchAction doesn't need to pass the key since it truly is the
method name being called, but not in the case of DispatchKeyAction where the
Map can point several keys to the same method which is a very handy feature.

> And some point between Struts 1.x and Struts 2.x, I'd like apply a great
> many instances of "extract method" throughout the framework, since many
> of our methods are a trifle long.

Yes, they are!  And subclassing is difficult.  Nothing a bit of refactoring
can't fix fairly easily though.

    Erik



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Ted Husted <hu...@apache.org>.
Erik Hatcher wrote:
> Obviously my only use-case/need right now is to have an additional String
> key parameter passed to a perform-like method.  So I'm ok with locking it
> into that method signature if that'll get it committed, but I still think a
> DispatchAction subclass should be more extensible than that.  Maybe you're
> proposing something more extensible and I'm just not seeing it yet though.

The String key would be passed up in LookupKeyAction version, and
developers using this one would subclass the "extended" perform method. 

With DispatchKeyAction, the key is used to call the method itself and
does not need to be passed. Since reflection is being used, the key is
implicit in the name of the method invoked.

In order to pass a parameter, it has to come from somewhere. Everything
that perform "knows" is in the original signature, where any reflected
method can get it. 

Actions often need to pull properites and parameters out of the request
and mappings. But this is best handled by other utility methods in the
class, that each reflective method could call. 

So if the use-case is I want to pass "glockenspeil" from the request,
then the class should have a protected "String getGlockenspiel(request)"
method that any of the reflective methods could call (and an additional
subclass could override).

I've annexed a DispatchAction with the initial refactoring I mentioned.
The idea is that you could start by extending this, overriding perform
with your own method-name discovery routine, and then call 

return dispatchMethod(mapping,form,request,response,name);

at the end (without calling super.perform(...) at any point).

Of course, additional refactoring to encapsulate error handling could be
done, since we call the same "sendError" block several times, but it
would just be more instances of "extract method".

And some point between Struts 1.x and Struts 2.x, I'd like apply a great
many instances of "extract method" throughout the framework, since many
of our methods are a trifle long. 


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/struts/

Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
----- Original Message -----
From: "Ted Husted" <hu...@apache.org>
> > - Standardizing on the class names.  I suggest yours be renamed
> > LookupDispatchKeyAction, since LookupAction is pretty generic and there
will
> > be several "lookup" style base classes.
>
> I'd like to keep the "dispatch" moniker out of this one, since it makes
> it sounds like it uses the reflective dispatch mechanism. But
> LookupKeyAction works for me. The other could be shortened to
> DispatchKeyAction, if you like.

Sounds good to me.  +1

> All that perform knows, that another method would not, is in the
> original signature. I do sometimes extract information from the mapping
> or request, and then pass that back to a method with an extended
> signature, but I think in practice that would be another dispatch
> mechanism, and both techniques would not be used at the same time. Do
> you have a use-case for this feature?

I don't have any use-case for making the getMethod/invokeMethod any more
generalized except that as it exists now DispatchAction is not cleanly
subclassable.  Allowing DispatchAction to keep the cache of methods, and to
find methods extensibly so that a method signature is passed into the
getMethod seems like a good refactoring.  I can't quite follow exactly how
you are proposing the change, but I'm happy with it if you mean something
along the lines as what I'm saying.

> As it stands, we could extract into another method the fragment from the
> orignal DispatchAction below
>
> "// Identify the method object to be dispatched to"
>
> and pass it the "name" to end the method.

Can't it just take the Object[] of types rather than it being a member
variable of DispatchAction?  Then subclasses could take advantage of the
getMethod (String name, Object[] types).  The dilemma is then if a subclass
passed in two of the same name's with different signatures - how could we
handle that so that its not possible for a subclass to look for different
signatures, or make the caching mechanism take into account method signature
as well.

Obviously my only use-case/need right now is to have an additional String
key parameter passed to a perform-like method.  So I'm ok with locking it
into that method signature if that'll get it committed, but I still think a
DispatchAction subclass should be more extensible than that.  Maybe you're
proposing something more extensible and I'm just not seeing it yet though.

> Another class could then extend DispatchAction, override perform, obtain
> its
> own method name in its own way, and then call that same method at the
> end.

I guess I'm just proposing that DispatchAction provide a little more such
that it can handle getting methods in an extensible way, so subclasses don't
have to do as much work.  Obtaining the method will be the same for all
except for the signature, right?

> > One other comment - I currently prefer using the reflection dispatching
> > because I'd rather not see a whole bunch of 'if' statements like if
> > ("button.add".equals(key)), but I definitely agree that its useful to
have a
> > more generic dispatch just passing the key.
>
> Personally, I've started to specify lightweight helper objects as the
> parameter property. A single standard Action can then instantiate and
> invoke these objects from within perform. Additional standard
> functionality is specified through ActionForwards. While this can leads
> to a larger configuration file, it severly reduces the number of Struts
> Actions in the game, and enforces the use of business objects.

Doesn't the decrease in Struts Actions equal the increase in the helper
objects?

    Erik



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Ted Husted <hu...@apache.org>.
Erik Hatcher wrote:
> - Standardizing on the class names.  I suggest yours be renamed
> LookupDispatchKeyAction, since LookupAction is pretty generic and there will
> be several "lookup" style base classes.

I'd like to keep the "dispatch" moniker out of this one, since it makes
it sounds like it uses the reflective dispatch mechanism. But
LookupKeyAction works for me. The other could be shortened to 
DispatchKeyAction, if you like.


> - Unifying how we deal with getMethod and invokeMethod into a common
> base-class or via a helper utility class. No point in all our classes having
> cut and pasted code.  My suggestion is to have a common DispatchAction base
> class for all of our lookup base classes where the getMethod can be added
> more generically in some way.  The issue here is, of course, how to deal
> with subclasses that want to find different method signatures.  I used an
> Object[] in my class - maybe thats the way to go, or some derivation
> thereof.

All that perform knows, that another method would not, is in the
original signature. I do sometimes extract information from the mapping
or request, and then pass that back to a method with an extended
signature, but I think in practice that would be another dispatch
mechanism, and both techniques would not be used at the same time. Do 
you have a use-case for this feature?

As it stands, we could extract into another method the fragment from the
orignal DispatchAction below 

"// Identify the method object to be dispatched to"

and pass it the "name" to end the method.

Another class could then extend DispatchAction, override perform, obtain
its
own method name in its own way, and then call that same method at the
end.


> One other comment - I currently prefer using the reflection dispatching
> because I'd rather not see a whole bunch of 'if' statements like if
> ("button.add".equals(key)), but I definitely agree that its useful to have a
> more generic dispatch just passing the key.

Personally, I've started to specify lightweight helper objects as the
parameter property. A single standard Action can then instantiate and
invoke these objects from within perform. Additional standard
functionality is specified through ActionForwards. While this can leads
to a larger configuration file, it severly reduces the number of Struts
Actions in the game, and enforces the use of business objects.

-Ted.

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
Ted,

Attached is my revised and renamed LookupDispatchMethodAction class.  It
tackles the reflection option, whereas yours tackles the simple perform
method invocation.  We should unify the two by bringing by:

- Standardizing on the class names.  I suggest yours be renamed
LookupDispatchKeyAction, since LookupAction is pretty generic and there will
be several "lookup" style base classes.

- Unifying how we deal with getMethod and invokeMethod into a common
base-class or via a helper utility class. No point in all our classes having
cut and pasted code.  My suggestion is to have a common DispatchAction base
class for all of our lookup base classes where the getMethod can be added
more generically in some way.  The issue here is, of course, how to deal
with subclasses that want to find different method signatures.  I used an
Object[] in my class - maybe thats the way to go, or some derivation
thereof.

- Test cases - I'm as guilty as anyone, but Struts really needs more test
cases.  I went looking for them and only found a few test cases in the
Struts CVS, one for ActionServlet, and three tag ones.  If there were some
more for Actions and ActionForm's then I would have derived one quickly, but
there are no examples to follow.  For this particular class, I'd like to use
Deryl's mock objects one since the main test is to verify that methods are
being dispatched properly.  Deryl?  Could you get us started on such an
example?  I'll give it a shot whenever I get some "down time" to fiddle with
it.

Any comments/suggestions on these items?

I still eventually, if no one beats me to it, want to create another pair of
base classes like this to handle the parameter name changing rather than the
parameter value - this is where the graphical buttons could be handled
automatically by checking for a request attribute "add" or "add.x".

One other comment - I currently prefer using the reflection dispatching
because I'd rather not see a whole bunch of 'if' statements like if
("button.add".equals(key)), but I definitely agree that its useful to have a
more generic dispatch just passing the key.

Thats all for now!

    Erik


----- Original Message -----
From: "Ted Husted" <hu...@apache.org>
To: "Struts Developers List" <st...@jakarta.apache.org>
Sent: Saturday, November 24, 2001 10:53 AM
Subject: Re: [SUBMIT] LookupDispatchAction - how to handle multiple
html:submit buttons


> Erik Hatcher wrote:
> > I believe I might have made this class a little too feature-rich and
perhaps
> > it should be broken into two base classes - one to dispatch via
reflection
> > to a Map specified mapping between key and method, and another to do the
> > dispatching to an enhanced perform method taking the key.  With two
separate
> > base classes the getKeys, getKeyMethodMap and perform could all be made
> > abstract and remove some likely usage confusion.
>
> I think having two base classes here is a good idea. Here's a first
> blush at a separate LookupAction that doesn't use the reflection
> techniques from DispatchAction.
>
> It's possible that DispatchAction should be refactored so that invoking
> the method is separated from determining the method name. This way a
> LookupDispatchAction, and others, could determine the method name by
> whatever means they like, and then pass that back.
>
> The idea being that the part in DispatchAction below
>
> "// Identify the method object to be dispatched to"
>
> could be moved into another method that would finish up, like
>
>     public ActionForward dispatch(ActionMapping mapping,
> ActionForm form,
> HttpServletRequest request,
> HttpServletResponse response,
> String name)
>
> and the current DispatchAction (or any subclasses) would end with
>
> return (dispatch(mapping,form,request,response,name));
>
> eanwhile, I'm working on adding multibutton submits to "struts-simple"
> (which really needs to be renamed), to demonstrate the various
> techniques people use, which include
>
> 1) Conventional Javascript
> 2) Javascript via a tag
> 3) Lookup key from label (annexed)
> 4) Lookup key from list (not covered in this thread)
> 5) Lookup key and dispatch
> 6) Relay to local forward (my personal favorite)
>
> I'm glad this thread came up. I orginally steered clear of
> DispatchAction, since it seemed like that the "other" performs would
> share a lot of error handling code. I have finally realized that it is
> trivial to factor the common code into local methods (keeping everything
> on the stack), so that the "other" performs (nomenclature, anyone?)
> could really just differ by which business logic method they call.
>
> It also occurs to me that if you wanted to handle something in another
> Action, the "other" perform could just return a forwarding to another
> Action. So, you can mix and match the "many" versus "few" Action
> strategies as needed.
>
>
> -- Ted Husted, Husted dot Com, Fairport NY USA.
> -- Custom Software ~ Technical Services.
> -- Tel +1 716 737-3463
> -- http://www.husted.com/struts/
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>
>

Re: [SUBMIT] LookupDispatchAction - how to handle multiple html:submit buttons

Posted by Ted Husted <hu...@apache.org>.
Ted Husted wrote:
> Here's a first
> blush at a separate LookupAction that doesn't use the reflection
> techniques from DispatchAction.

Attached, this time.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/struts/