You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Rick Reumann <r...@reumann.net> on 2004/09/09 18:34:05 UTC

Trying to come up with a Mapping-Dispatch combo Action

Not sure which list this question/topic really belongs on so posting to 
both. (I'm bringing it up on the dev list because I'm thinking maybe the 
base MappingDispatchAction could/should be modified).

Some design background. I like to keep related tasks belonging in one 
Dispatch Action class (flavor to be discussed). This is a typical 
approach, yet one of the problems is desided on the type of 
DispatchAction ... keep it DispatchAction or use one of the subclasses 
LookupDispatch or MappingDispatch.

First off I really don't like the LookupDispatchAction. I've used it 
extensively in a large application and it becomes a real pain. It 
becomes really ugly to use when you start having some generic button 
names that you reuse for different things. For example a changing 
requirment was that we ended up having to use a button called "Ok" a lot 
(I know stupid). So sometimes "Ok" would submit to the same 
LookupDispatchAction but would need to access different methods. You 
end up then having to create 'fake' button names in your resources file 
just so the LookupDispatchAction can work correctly. Maintenance of the 
LookupDispatch can be a pain also. Anyway...

Until the MappingDispatchAction, I've been relatively content with using 
a standard DispathAction. What I like about the MappingDispatchAction is 
that it works really nicely for links - you don't have to append a 
dispatch parameter name to the URL. It's also nice for typical forms 
since you don't have to provide a hidden dispatch parameter on the page.

The only problem I'm running into it is when you have a form with more 
than one button and each button should call a different dispatch method. 
I haven't really figured out a good way to work this out with the 
MappingDispatchAction.  I think trying to change the form's action 
attribute using JavaScript will be ugly (assuming it can even be done, 
I've never tried it). The only solution I can think of at the moment 
would be to override the getMethodName method of MappingDispatch and 
provide an extra mapping in your config where the parameter would change 
to something like parameter="dispatchMethod"

The overridden getMethodName might look like

protected String getMethodName(
         ActionMapping mapping,
         ActionForm form,
         HttpServletRequest request,
         HttpServletResponse response,
         String parameter)
         throws Exception {
	
	if( "dispatchMethod".equals( parameter ) {
         	parameter = request.getParameter(parameter);
	}
         return parameter
     }

This would allow you to use the MappingDispatchAction like a 
DispatchActoin when needed. The only caveat is you would have to make 
sure the if statement in the above is what you wanted. (Probably better 
to pull the parameter name "dispatchMethod" from a properties file or 
constants class).

Maybe there is a much better way to accomplish what I'm concerned with?

-- 
Rick


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Last try.  Sorry about the noise:Rick Generic Action Solution



<link>----|
          |
<image>---|--- to updateFooBar.do of some GenericAction class.
          |
<submit>--|





Michael Generic Taglib Solution



        
<link>----|
          |   A: Solution Facade Interface:
<image>---|      <facase: link, image, submit, file, etc.>
          |---B: Solution Implementation:
          |      Unconnected to anything [Unknown Code]
          |   C: Generic Request Handler: updateFooBar.x
<submit>--|      gives the action updateFooBar
          |      for all of these, in and out of Struts,
<file>----|      e.g. with DispatchAction.


>
>
>
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Hoping this comes out better:
Rick Generic Action Solution


<link>------|
                   |
<image>---|--- to updateFooBar.do of some GenericAction class.
                 |
<submit>--|


Michael Generic Taglib Solution
        
<link>----|
                  |   A: Solution Facade Interface:
<image>---|      <facase: link, image, submit, file, etc.>
                  |---B: Solution Implementation:
                  |      Unconnected to anything [Unknown Code]
                 |   C: Generic Request Handler: updateFooBar.x
<submit>--|      gives the action updateFooBar
                 |      for all of these, in and out of Struts,
<file>---- |      e.g. with DispatchAction.


>
>
>
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Rick Reumann wrote:

> Some comments below...
>
> Michael McGrady wrote the following on 9/13/2004 5:40 PM:
>
>
> Yes, that is a slight benefit (which is the same benefit of using the 
> regular DispatchAction), however, the slight cost of having to rely on 
> the struts-config for deciding what dispatch method is going to be 
> called is worth it for the sake of consistency, since I don't have to 
> worry about whether it's a link, button, image, or form submit. If I 
> didn't want to use the struts-config simply using the standard 
> DispatchAction works fine as well. Consistent.


I think what you are saying is that you like to use one action for 
various view tags.  So, you are looking for a struts action that gives 
you one action for links, buttons, imges, and submits.  (You don't 
include, for good reason, the browse button for file uploads.) 

Rick Generic Action Solution

<link>----------|
                         |
<image>------- | ------ to updateFooBar.do of some GenericAction class.
                         | 
<submit>------  |

Michael Generic Taglib Solution

<link>----------|
                         |
<image>------- |
                         |              A:    Solution Facade Interface: 
<facase: link, image, submit, file, etc.>
                         | -------  B:    Solution Implementation: 
Unconnected to anything [Unknown Code]
                         |             C:    Generic Request Handler: 
updateFooBar.x gives the action updateFooBar for all of these,
                         |                     in and out of Struts, 
e.g. with DispatchAction.
<submit>-------|
                         |
<file>-----------|

So, I guess we are doing things a bit differently but in a very 
connected way both coding-wise and "philosophy-wise".  Right?  I still 
am EXTREMELY interested in your questions and your progress.  If I am 
not mistaken, you can use DispatchAction to do what you want with my 
solution.  I am beginning to see the use of your concerns with respect 
to Struts.  In fact, something not unlike DispatchAction can be used to 
do what you with my solution outside of struts entirely.  Isn't that 
correct?  Perhaps the two together could form a real dynamo?  I have 
more in the wings working with the taglibs sandbox image stuff, which is 
excellent, by the way.

Michael McGfady





---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Rick Reumann wrote:

> Some comments below...
>
> Michael McGrady wrote the following on 9/13/2004 5:40 PM:
>
> Thanks for your comments below. It has helped clarify things. Your 
> approach is pretty nice but in the above how would you be able to use 
> this same Action for regular links? It seems like you have tied this 
> Action to requiring use of hte ImageTagUtil which doesn't make too 
> much sense for when you'd want to get to this action class from a 
> standard link?


Hi, Rick,

We are getting someplace here, I think.  I don't use this Action at 
all.  I just made this little class up to show what I was talking 
about.  Tying the solution to these things just ruins performance and 
flexibility.  Decoupling, I have always thought, is like Aaron 
Nitzovitch's theory of "over protection" in chess.  If you have too much 
protection on a square, then none of the pieces involved is critical and 
so all are free to operate as offensive weapons.  What I am trying to 
say is that I use a Facade, which means that the Facade is the standard 
interface for all the differing page operations we were discussing.  I 
don't try to use an Action or any other particular solution outside the 
Facade to do this.  The <crackwillow:image/>, <crackwillow:file/>, 
<crackwillow:link/> , ... , etc. tag is the Facade.  I am trying to 
advocate that the correct solution for a generic approach is a Facade 
represented by a taglib covering all the options that are relevant.  
This Facade is not even wedded to struts.  I do use struts, but that is 
not necessary.  That is but a "component" of the mix behind the Facade.  
That's what I do.  Now, can you expand on what you do with 
MappedLookupAction? 

I suspect we are working on differing attempts at "generic apporaches".  
Mine is related to what is written on the JSP page and yours, I think, 
is related to finding a generic approach with struts actions.  Exactly 
what you are doing is not clear to me. 

By the way, did you see the post by Craig on MappedLookupAction today?

Michael McGrady


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Rick Reumann <st...@reumann.net>.
Some comments below...

Michael McGrady wrote the following on 9/13/2004 5:40 PM:

> The following class works fine:
> 
>    public abstract class CrackWillowLookupDispatchAction
>            extends DispatchAction {
> 
>      public ActionForward execute(
>        ActionMapping mapping,
>        ActionForm form,
>        HttpServletRequest request,
>        HttpServletResponse response)
>            throws Exception {
>            String methodName = ImageTagUtil.getName(request);
>        return dispatchMethod(mapping, form, request, response, methodName);
>      }
>    }

Thanks for your comments below. It has helped clarify things. Your 
approach is pretty nice but in the above how would you be able to use 
this same Action for regular links? It seems like you have tied this 
Action to requiring use of hte ImageTagUtil which doesn't make too much 
sense for when you'd want to get to this action class from a standard 
link? (This was also my problem with the LookupDispatchAction that I 
didn't like... MappingDispatchAction solves all of this).

> The other issues about this action have nothing to do with what I have 
> been talking about, I think.
> 
>    <html:form name='lookupForm' method='get' action='lookup.do' 
> type='com.crackwillow.struts.form.LookupForm'>
>            <input type='submit' name='add.x' value='add'>
>            <input type='submit' name='delete.x' value='delete'>
>    </html:form>
> 
> This requires nothing in struts-config.xml.

Yes, that is a slight benefit (which is the same benefit of using the 
regular DispatchAction), however, the slight cost of having to rely on 
the struts-config for deciding what dispatch method is going to be 
called is worth it for the sake of consistency, since I don't have to 
worry about whether it's a link, button, image, or form submit. If I 
didn't want to use the struts-config simply using the standard 
DispatchAction works fine as well. Consistent.

<snip>

> 
>    What my image is has nothing to do with what the name value is.  The
>    name value is the command and is completely decoupled from the
>    image.  

Yes, I see that now. That's good. Thanks for that clarification.

>    The following simple code, in my solution, can replace a hugely
>    complex series of relations and code in LookupActionMapping which
>    drive you crazy and make any connection with ActionMapping's
>    parameter attribute unnecessary as well.

Agreed. And definitely if I was going to go with a dispatch approach 
that relied on img/button names yours is a much more elequent solution. 
(I still like an onClick to a MappingDipsatchAction though:)


-- 
Rick

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
I am enjoying the discussion as well. 

I can see that your schedule and my attempting to say too much are 
confusing things.  Let me also clarify a couple things so we are clear 
what we each are saying.  Then I will address the bigger issues.

The following class works fine:

    public abstract class CrackWillowLookupDispatchAction
            extends DispatchAction {

      public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
            throws Exception {
            String methodName = ImageTagUtil.getName(request);
        return dispatchMethod(mapping, form, request, response, methodName);
      }
    }

The other issues about this action have nothing to do with what I have 
been talking about, I think.

    <html:form name='lookupForm' method='get' action='lookup.do' 
type='com.crackwillow.struts.form.LookupForm'>
            <input type='submit' name='add.x' value='add'>
            <input type='submit' name='delete.x' value='delete'>
    </html:form>

This requires nothing in struts-config.xml.

I.  Clarifications

    A.  Code Inside ActionForm Topic

    The code I use for determining which <input type='image'> button has
    been pressed is this utility class and this utility class alone. 

public class ImageTagUtil {
  public static String getName(HttpServletRequest request) {
    String command = null;
    String buttonValue = null;
    Enumeration enum = request.getParameterNames();

    while(enum.hasMoreElements()) {
      buttonValue = (String)enum.nextElement();
      if(buttonValue.endsWith(".x")) {
        command = buttonValue.substring(0,buttonValue.indexOf('.'));
      }
    }
    return command;
  }
}

    The code in the form (inner class buttons) is an improvement on
    other solutions where there are button classes used.  I don't like
    those solutions, including mine, which I think is better than the
    usual.  The usual solution ends up really heavy with loads of
    buttons populating the situation,whereas this solution (which I
    don't like, remember) uses one inner button and one only.  But, I
    don't use this at all.  I removed it from the wiki as too complicating.

    B.  Different Commands for Different Images

    What my image is has nothing to do with what the name value is.  The
    name value is the command and is completely decoupled from the
    image.  Neither has anything to do with the other.  You can change
    the image to anything you want and you can change the command to
    anything you want.  This is clearly true with the html too.  <input
    type='image' src='whatever.gif' name='whatever'> clearly decouples
    what the gif is and what the name attribute value is.  I extend this
    by providing a tag which will produce an image with says whatever
    it's name is: 'WHATEVER.gif' will be a gif with "WHATEVER",
    'Whatever.jpg' will be a jpeg with "Whatever".  So, we can have
    "OK.gif" with name='viewFoo' and "OK.gif" with name='updateFoo'. 
    That is not a problem.  If they later decide that they want
    "Yahoo.gif" or "GO.jpg" instead of "OK.gif", all you have to do is
    change it and nothing else changes at all. 

II.  Issues

    A.   LookupActionMapping  

    My solution does not say a thing about using or not using the idea
    of executing a method by something like LookupActionMapping.  Rather
    it is wholly about how to mine the values from the HTML.

    The following simple code, in my solution, can replace a hugely
    complex series of relations and code in LookupActionMapping which
    drive you crazy and make any connection with ActionMapping's
    parameter attribute unnecessary as well.

    execute(execute(ActionMapping mapping, ActionForm
    form,HttpServletRequest request, HttpServletResponse response) {
               return dispatchMethod(mapping, form, request, response,
    ImageTagUtil.getName(request));
    }

    So, the LookupActionMapping requires you IN ORDER TO ACHIEVE THE
    SAME THING to give the parameter attribute a value in the action
    mapping of struts-config.xml whereas my solution is completely
    decoupled from that.  The LookupDispatchAction requires you to
    implement keyMethodMap relating methods to both the JSP and the
    action mapping of struts-config.xml.  The fact that
    LookupDispatchAction uses reflection is important, of course, but is
    completely irrelevant to the principal ideas that
    LookupDispatchAction is based on.  Other ways of mining the value of
    the method to be used can equally subclass DispatchAction.


Michael McGrady






---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Rick Reumann <st...@reumann.net>.
(not commenting below, just up top on this)

In reference to your first comment:

 > I think that what appears to be a model emphasis for the
 > solution in your [rick's] approach is bound to fail.  Further, making 
 > the
 > solution view based frees the model to be built for performance, which
 > is why I use the solution I sent to you with respect to images, i.e.
 > the image tag for submits.

Maybe you are misunderstanding what I'm doing. My approach has nothing 
to do with the model at all. All I have is a very simple 
MappingDispatchAction with typical dispatch methods.

All my links, forms, or image 'onClicks' simply equate to a standard 
mapping (ie /updateFooBar.do... /viewFooBars.do, etc). So a developer 
can ALWAYS easily tell what is being called (of course to see the actual 
method being called he/she will need to look in the struts-config but 
it's consistent across all types of front end calls.

I saw two things in the initial e-mail that had me concerned. One was 
where the tag had this code:

if(buttonValue.endsWith(".x")) {
        command = buttonValue.substring(0,buttonValue.indexOf('.'));
      }
    }
    return command;

The second was all the code you added inside of your ActionForm 
subclass... even to the extent that it needs to contain an inner class. 
I just find this to be way overcomplicated for something that I think 
should be pretty simple.

In reference to my first concern... How would you have two different 
commands executed for a button with the same name? In my case here at 
work, we had to develop this one app where we needed to use an "Ok" 
button. If I was on an edit page I needed to still have an "Ok" button 
and when on an insert page I still had to use the same "Ok" button. 
Looks like in your above, this would end up calling on the one type of 
method. (It also looked like you would run into the same problem with 
the CrackWillowButton class).

I guess what I am missing is what your approach gains me verses using 
just a 'tiny' amount of javascript. (I'm not one to believe that a web 
application in today's world should be required to work without ANY 
javascript).

I'll sum up my approach with examples and would love to hear the 
problems with it. Keep in mind the advantage (I think) to this is that 
you simple code your standard MappingDispatchAction and that you can 
'easily' see what is being called. In ALL the example below you easily 
see the action being called (no need to figure what underlying 
implementation is taking care of figuring out what dispatch method to 
call, you easily can just look at your mapping and find out.)

Enjoying this discussion. Hopefully below it makes it more clear what 
I'm doing:

UserAction of type MappingDispatchAction with some typical dispatch methods
    ie updateUser, insertUser, deleteUser, getUser, getUsers

(mappings in struts-config could look identical to the above which of 
course map to "UserAction")

Different ways you could get access to the methods:

1) From a link. (I like JSTL even though a bit more verbose than html:link):

<c:url var="url" value="/getUsers.do"/><a href="${url}">[ Get Users ]</a>


2) From a typical form with one submit button

<html:form action="/updateUser">
<html:submit><fmt:message key="button.update"/></html:submit>

3) For images or buttons

<c:url var="url" scope="page" value="/getUser.do">
     <c:param name="id" value="${user.id}"/>
</c:url>
//on button or img onClick, or I usually make this a js function:
window.location='${url}'


4) When you need different submit buttons for one form

//create a javascript function. I keep this in my header.jsp
//Thanks Bill (I think it was Bill S. who posted this:)

function swapAction( formName, action) {
     formAction = document.getElementById( formName ).action;
     newAction = '<html:rewrite page="/'+action+'.do"/>';
     document.getElementById( formName ).action = newAction;
}

//then on different submit buttons
<html:submit onclick="swapAction( 'userForm', 'updateUser')">
    <fmt:message key="button.update"/>
</html:submit>


Michael McGrady wrote the following on 9/13/2004 11:09 AM:

> SEE WITHIN:
> 
> Michael McGrady
> 
> Rick Reumann wrote:
> 
> I hope you have a bit of time to discuss this in detail, Rick, because 
> the amount of activity in this area is huge.  I think this is one of 
> those areas, along with looking for persistence not identical to the 
> normal scopes, where there is continued dissatisfaction.
> 
>>
>> First I'd like to point out that I like to keep an application as 
>> consistent as possible. That means that I like my links, my form 
>> submits, my buttons to all act similarly - this makes it very easy for 
>> a new developer to the project to figure out what is going on.
> 
> 
> I do too.  My generic solution is based on what appears on the "coded" 
> page.  I wanted to decouple that from everything else.  I, therefore, 
> use a variation of the FACADE PATTERN with these, emphasizing a generic 
> solution from the VIEW perspective rather than from the MODEL 
> perspective.  I think that what appears to be a model emphasis for the 
> solution in your approach is bound to fail.  Further, making the 
> solution view based frees the model to be built for performance, which 
> is why I use the solution I sent to you with respect to images, i.e. the 
> image tag for submits.
> 
> There simply is not a model based generic solution, in my opinion, which 
> sometimes if right and sometimes is wrong.  (I also include <input 
> type='file'>, by the way, in addition to your list.)  I think you have 
> to use something like the Facade Pattern because the actual logic 
> underlying these view related behaviors is so different.  If you try to 
> disseminate a generic solution in the model, you are bound to run into 
> the types of problems you have discussed.  So, essentially, I have 
> developed a taglib that looks like this:
> 
> GENERIC PAGE BASED SOLUTION
> 
>        <crackwillow:image
>            button='Crack_Willow_Chat.gif'
>            mapBean='hkc'
>            bgClrCode='banRtBgClr'
>            txtClrCode='banRtTxtClr'
>            font='Edwardian Script ITC'
>            italic='false'
>            bold='true'
>            size='30'
>            property='chatSend'/>
> 
> The key here is the "image".  If you wanted to browse with an input type 
> of file, this would be "file".  This produces a GIF button saying "Crack 
> Willow Chat" in Edwardian Script ITC embolded with a size of 30 and a 
> coded identification of the command as "chatSend" and whatever colors 
> happen to be represented in this space by the values of bgClrCode 
> (background color) and txtClrCode (text color).  If you want a jpeg, put 
> in ".jpg", etc.  If you don't want a button, just drop ".gif" entirely.
> The behavior of the button is changed by changing "image", e.g. 
> "submit", "link", "file".  The view value of the button itself is 
> changed by changing the value of "button".  This is fully localized.  If 
> you don't want a   And the property you want to send is changed with a 
> change in "property".  The colors are dynamic here with bgClrCode and 
> txtClrCode.  If you wanted to hard code them, you would with bgClr and 
> txtClr.  The value of property can be dynamic or not.  This depends on 
> the model coders.  The map bean, which is instrumented, allows me to 
> connect the dynamic colors with other colors on a page, which are held 
> in the same bean.  Any other model solution for that problem can easily 
> be plugged into this solution.
> 
> Here is the rub or the main point.  The solution I sent to you is 
> decoupled from this page code, emphasizing the use of the Facade 
> Pattern.  Accordingly, I send parts of my solution out each time a 
> question comes up in the area, but never the whole solution, which is 
> too involved for simple posts.  (Images, for example, are created 
> dynamically and cached.)
> 
> This solution presently lets me just put in my buttons and have no 
> concern at all for what happens in the background.  Some parts of the 
> solution, e.g. for <input type='file'>, will generate JavaScript and 
> others won't.  I use a mock image over the "live" image of the file 
> browse button in order to get dynamic, image buttons for the browse 
> button that are consistent with the security protocols for <input 
> type='file'>.  Further, the background code for this is decoupled from 
> the model because the model simply has to deal with results rather than 
> with mining the results.  I place the class* */ImageTagUtil /cited in my 
> last to you between the form and the Action.  Thus, Actions don't care 
> if it is an image, a submit, or whatever.
> 
> You get the idea.  What do you think?
> 
> Michael McGrady
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 


-- 
Rick

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
SEE WITHIN:

Michael McGrady

Rick Reumann wrote:

I hope you have a bit of time to discuss this in detail, Rick, because 
the amount of activity in this area is huge.  I think this is one of 
those areas, along with looking for persistence not identical to the 
normal scopes, where there is continued dissatisfaction.

>
> First I'd like to point out that I like to keep an application as 
> consistent as possible. That means that I like my links, my form 
> submits, my buttons to all act similarly - this makes it very easy for 
> a new developer to the project to figure out what is going on.

I do too.  My generic solution is based on what appears on the "coded" 
page.  I wanted to decouple that from everything else.  I, therefore, 
use a variation of the FACADE PATTERN with these, emphasizing a generic 
solution from the VIEW perspective rather than from the MODEL 
perspective.  I think that what appears to be a model emphasis for the 
solution in your approach is bound to fail.  Further, making the 
solution view based frees the model to be built for performance, which 
is why I use the solution I sent to you with respect to images, i.e. the 
image tag for submits.

There simply is not a model based generic solution, in my opinion, which 
sometimes if right and sometimes is wrong.  (I also include <input 
type='file'>, by the way, in addition to your list.)  I think you have 
to use something like the Facade Pattern because the actual logic 
underlying these view related behaviors is so different.  If you try to 
disseminate a generic solution in the model, you are bound to run into 
the types of problems you have discussed.  So, essentially, I have 
developed a taglib that looks like this:

GENERIC PAGE BASED SOLUTION

        <crackwillow:image
            button='Crack_Willow_Chat.gif'
            mapBean='hkc'
            bgClrCode='banRtBgClr'
            txtClrCode='banRtTxtClr'
            font='Edwardian Script ITC'
            italic='false'
            bold='true'
            size='30'
            property='chatSend'/>

The key here is the "image".  If you wanted to browse with an input type 
of file, this would be "file".  This produces a GIF button saying "Crack 
Willow Chat" in Edwardian Script ITC embolded with a size of 30 and a 
coded identification of the command as "chatSend" and whatever colors 
happen to be represented in this space by the values of bgClrCode 
(background color) and txtClrCode (text color).  If you want a jpeg, put 
in ".jpg", etc.  If you don't want a button, just drop ".gif" entirely. 

The behavior of the button is changed by changing "image", e.g. 
"submit", "link", "file".  The view value of the button itself is 
changed by changing the value of "button".  This is fully localized.  If 
you don't want a   And the property you want to send is changed with a 
change in "property".  The colors are dynamic here with bgClrCode and 
txtClrCode.  If you wanted to hard code them, you would with bgClr and 
txtClr.  The value of property can be dynamic or not.  This depends on 
the model coders.  The map bean, which is instrumented, allows me to 
connect the dynamic colors with other colors on a page, which are held 
in the same bean.  Any other model solution for that problem can easily 
be plugged into this solution.

Here is the rub or the main point.  The solution I sent to you is 
decoupled from this page code, emphasizing the use of the Facade 
Pattern.  Accordingly, I send parts of my solution out each time a 
question comes up in the area, but never the whole solution, which is 
too involved for simple posts.  (Images, for example, are created 
dynamically and cached.)

This solution presently lets me just put in my buttons and have no 
concern at all for what happens in the background.  Some parts of the 
solution, e.g. for <input type='file'>, will generate JavaScript and 
others won't.  I use a mock image over the "live" image of the file 
browse button in order to get dynamic, image buttons for the browse 
button that are consistent with the security protocols for <input 
type='file'>.  Further, the background code for this is decoupled from 
the model because the model simply has to deal with results rather than 
with mining the results.  I place the class* */ImageTagUtil /cited in my 
last to you between the form and the Action.  Thus, Actions don't care 
if it is an image, a submit, or whatever.

You get the idea.  What do you think?

Michael McGrady


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Rick Reumann <st...@reumann.net>.
Hi Michael. I'm replying to his quickly before I run into work so I 
might not have looked these approaches over enough but here are my first 
impressions.

First I'd like to point out that I like to keep an application as 
consistent as possible. That means that I like my links, my form 
submits, my buttons to all act similarly - this makes it very easy for a 
new developer to the project to figure out what is going on.

Concerning the first approach, it appears the type of command called has 
to match the button name. I don't like this approach at all. Sometimes 
you later need to change the button names or even a worse scenario, you 
sometimes need to have the same button name used on different forms go 
to the same Action class but call a different dispatch method (for 
example with the "ok" or "proceed" button).

The second approach runs into some of the same of problems as the 
LookupDispathAction.. maintenance problems. In that approach you have to 
maintain what action method gets called by editing an ActionForm class. 
This becomes sort of unintuitive. It works but to me it just does 
provide for a consistent approach.

What I like about the simple use of MappingDispatchAction, and using 
some extremely simple javascript for button situations, is that the 
approach is easy to follow. For a developer to figure what action 
dispatch method is going to be called he/she simply always can tell by 
the MappingDispatch mapping. This works for links, form submits and for 
button submits. (I'm thinking the later approach you mentioned would 
work with links and form submits but would then require you always pass 
in a request parameter that matches a button name similar to what you 
need to do when using a LookupDispatchAction).

Another feature I like of just always using a MappingDispatchAction is 
that maintenance seems easier. The only things you maintain are an 
action mapping in your struts config (which you always have to have 
anyway) and a dispatch method name (which you always need also). There 
is no need to worry about maintaining any button names and what they 
correspond to. You end up not caring about how they get to your Action 
dispatch method and you let the pure view(JSP) worry about calling the 
proper action mapping. Just my preference I guess for consistency's sake.


Michael McGrady wrote the following on 9/13/2004 2:48 AM:
> *The following is from 
> http://wiki.apache.org/struts/StrutsCatalogMultipleImageTagsSimplified 
> .  If you don't like this solution, I would be interested in your 
> thinking, Rick.  If you are interested, I have a comprehensive solution 
> to everything to do with buttons and images.  I am going to add to it, 
> but it is pretty well developed.
> *
> 
>    *This is an efficient way to end forever that pesky and recurrent
>    problem of how to use multiple image buttons in your forms. (N.B.:
>    This solution also works for non-image (submit) buttons by using
>    values like <input type="submit" name="add.x" value="add"> in the
>    submit button. Or, just use <input type="submit" name="button"
>    value="add"> for a different solution for <input type="submit">
>    versus <input type="image">)*
> 
>    *Assume that you have code not unlike:*
> 
> <input type='image' name='update' src='change.gif'>
> <input type='image' name='delete' src='nuke.gif'>
> 
>    *or, in Struts' image tag:*
> 
> <html:image property='submit' src='change.gif'/>
> <html:image property='delete' src='nuke.gif'/>
> 
>    *Now, how do we know which image has been clicked? The answer has
>    been complicated and costly in the past. Here is a simple way to
>    achieve everything at a low cost and with great flexibility and
>    freedom.*
> 
>    String button = null;
>    Enumeration enum = request.getParameterNames();
>    String parameterName = null;
>    while(enum.hasMoreElements()) {
>      parameterName = (String)enum.nextElement();
>      if(parameterName.endsWith(".x")) {
>        button = parameterName.substring(0,parameterName.indexOf('.'));
>      }
>    }
> 
>    *There you go. /If you clicked the image with name='submit', then
>    the variable button will have the value "submit"./ I suggest that
>    you toss out the LookupDispatchActions, the ButtonCommands, etc.
>    This is a done deal. You can clearly seek other ways to ensure a bit
>    more safety. For example, the code works equally as well with
>    "submit.button" as it does with "submit". Elegant, no, eh? I use a
>    class that encapsulates this functionality as follows:** *
> 
> *public class ImageTagUtil {
>  public static String getName(HttpServletRequest request) {
>    String command = null;
>    String buttonValue = null;
>    Enumeration enum = request.getParameterNames();
> 
>    while(enum.hasMoreElements()) {
>      buttonValue = (String)enum.nextElement();
>      if(buttonValue.endsWith(".x")) {
>        command = buttonValue.substring(0,buttonValue.indexOf('.'));
>      }
>    }
>    return command;
>  }
> }
> *
> 
>    *Surprisingly, some people still prefer the way I used to do this. I
>    think they just like the plain fanciness of it all. For those
>    people, here is code that is less extensible, more coupled, heavier,
>    etc. This code is comparatively not as good, in my opinion. There is
>    a further use of button objects which requires that you create a
>    separate button object for each image button you use on an html
>    page. That solution is very heavy and significantly affects the
>    footprint of a struts page. /If/ you are going to use buttons,
>    /which, again, is not recommended/, I would suggest the following
>    more lightweight version, which creates and then nulls one button
>    object per request. The use of an inner class allows the necessary
>    communications between the action form and the button class. *
> 
> *public class AdminButtonForm
>    extends ActionForm {
>  protected CrackWillowButton button;
>  protected String command;
> 
>  public CrackWillowButton getButton() {
>    if(button == null) {
>      this.button = new CrackWillowButton();
>    }
>    return button;
>  }
> 
>  public String getCommand() {
>    String hold = command;
>    command = null;
>    return hold;
>  }
> 
>  public void setCommand(String command) {
>    this.command = command;
>  }
> 
>  public void reset() {
>    button = null;
>  }
> 
>  public class CrackWillowButton {
>    private Integer x, y;
>    public static final String CREATE   = "create";
>    public static final String RETRIEVE = "retrieve";
>    public static final String UPDATE   = "update";
>    public static final String DELETE   = "delete";
>    public static final String SUBMIT   = "submit";
> 
>    public CrackWillowButton() {
>    }
> 
>    public CrackWillowButton getCreate()    {
>      setCommand(this.CREATE);
>      return button;
>    }
> 
>    public CrackWillowButton getRetrieve()    {
>      setCommand(this.RETRIEVE);
>      return button;
>    }
> 
>    public CrackWillowButton getUpdate()     {
>      setCommand(this.UPDATE);
>      return button;
>    }
> 
>    public CrackWillowButton getDelete() {
>      setCommand(this.DELETE);
>      return button;
>    }
> 
>    public CrackWillowButton getSubmit() {
>      setCommand(this.SUBMIT);
>      return button;
>    }
> 
>    public void setX(Integer x) {
>      if(y != null) {
>        reset();
>      } else {
>        this.x = x;
>      }
>    }
> 
>    public void setY(Integer y) {
>      if(x != null) {
>        reset();
>      } else {
>        this.y = y;
>      }
>    }
>  }
> }
> *
> 
>    *So, don't use buttons, but just mine the value of the [name].x
>    request parameter. *
> 
>    *Michael McGrady Cap't of the Eh Team*
> 
> Anyway, looking forward to you thinking on this.
> 
> Michael
> 
> Rick Reumann wrote:
> 
>> Not sure which list this question/topic really belongs on so posting 
>> to both. (I'm bringing it up on the dev list because I'm thinking 
>> maybe the base MappingDispatchAction could/should be modified).
>>
>> Some design background. I like to keep related tasks belonging in one 
>> Dispatch Action class (flavor to be discussed). This is a typical 
>> approach, yet one of the problems is desided on the type of 
>> DispatchAction ... keep it DispatchAction or use one of the subclasses 
>> LookupDispatch or MappingDispatch.
>>
>> First off I really don't like the LookupDispatchAction. I've used it 
>> extensively in a large application and it becomes a real pain. It 
>> becomes really ugly to use when you start having some generic button 
>> names that you reuse for different things. For example a changing 
>> requirment was that we ended up having to use a button called "Ok" a 
>> lot (I know stupid). So sometimes "Ok" would submit to the same 
>> LookupDispatchAction but would need to access different methods. You 
>> end up then having to create 'fake' button names in your resources 
>> file just so the LookupDispatchAction can work correctly. Maintenance 
>> of the LookupDispatch can be a pain also. Anyway...
>>
>> Until the MappingDispatchAction, I've been relatively content with 
>> using a standard DispathAction. What I like about the 
>> MappingDispatchAction is that it works really nicely for links - you 
>> don't have to append a dispatch parameter name to the URL. It's also 
>> nice for typical forms since you don't have to provide a hidden 
>> dispatch parameter on the page.
>>
>> The only problem I'm running into it is when you have a form with more 
>> than one button and each button should call a different dispatch 
>> method. I haven't really figured out a good way to work this out with 
>> the MappingDispatchAction.  I think trying to change the form's action 
>> attribute using JavaScript will be ugly (assuming it can even be done, 
>> I've never tried it). The only solution I can think of at the moment 
>> would be to override the getMethodName method of MappingDispatch and 
>> provide an extra mapping in your config where the parameter would 
>> change to something like parameter="dispatchMethod"
>>
>> The overridden getMethodName might look like
>>
>> protected String getMethodName(
>>         ActionMapping mapping,
>>         ActionForm form,
>>         HttpServletRequest request,
>>         HttpServletResponse response,
>>         String parameter)
>>         throws Exception {
>>         if( "dispatchMethod".equals( parameter ) {
>>             parameter = request.getParameter(parameter);
>>     }
>>         return parameter
>>     }
>>
>> This would allow you to use the MappingDispatchAction like a 
>> DispatchActoin when needed. The only caveat is you would have to make 
>> sure the if statement in the above is what you wanted. (Probably 
>> better to pull the parameter name "dispatchMethod" from a properties 
>> file or constants class).
>>
>> Maybe there is a much better way to accomplish what I'm concerned with?
>>
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 


-- 
Rick

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Trying to come up with a Mapping-Dispatch combo Action

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
*The following is from 
http://wiki.apache.org/struts/StrutsCatalogMultipleImageTagsSimplified 
.  If you don't like this solution, I would be interested in your 
thinking, Rick.  If you are interested, I have a comprehensive solution 
to everything to do with buttons and images.  I am going to add to it, 
but it is pretty well developed. 

*

    *This is an efficient way to end forever that pesky and recurrent
    problem of how to use multiple image buttons in your forms. (N.B.:
    This solution also works for non-image (submit) buttons by using
    values like <input type="submit" name="add.x" value="add"> in the
    submit button. Or, just use <input type="submit" name="button"
    value="add"> for a different solution for <input type="submit">
    versus <input type="image">)*

    *Assume that you have code not unlike:*

<input type='image' name='update' src='change.gif'>
<input type='image' name='delete' src='nuke.gif'>

    *or, in Struts' image tag:*

<html:image property='submit' src='change.gif'/>
<html:image property='delete' src='nuke.gif'/>

    *Now, how do we know which image has been clicked? The answer has
    been complicated and costly in the past. Here is a simple way to
    achieve everything at a low cost and with great flexibility and
    freedom.*

    String button = null;
    Enumeration enum = request.getParameterNames();
    String parameterName = null;
    while(enum.hasMoreElements()) {
      parameterName = (String)enum.nextElement();
      if(parameterName.endsWith(".x")) {
        button = parameterName.substring(0,parameterName.indexOf('.'));
      }
    }

    *There you go. /If you clicked the image with name='submit', then
    the variable button will have the value "submit"./ I suggest that
    you toss out the LookupDispatchActions, the ButtonCommands, etc.
    This is a done deal. You can clearly seek other ways to ensure a bit
    more safety. For example, the code works equally as well with
    "submit.button" as it does with "submit". Elegant, no, eh? I use a
    class that encapsulates this functionality as follows:** *

*public class ImageTagUtil {
  public static String getName(HttpServletRequest request) {
    String command = null;
    String buttonValue = null;
    Enumeration enum = request.getParameterNames();

    while(enum.hasMoreElements()) {
      buttonValue = (String)enum.nextElement();
      if(buttonValue.endsWith(".x")) {
        command = buttonValue.substring(0,buttonValue.indexOf('.'));
      }
    }
    return command;
  }
}
*

    *Surprisingly, some people still prefer the way I used to do this. I
    think they just like the plain fanciness of it all. For those
    people, here is code that is less extensible, more coupled, heavier,
    etc. This code is comparatively not as good, in my opinion. There is
    a further use of button objects which requires that you create a
    separate button object for each image button you use on an html
    page. That solution is very heavy and significantly affects the
    footprint of a struts page. /If/ you are going to use buttons,
    /which, again, is not recommended/, I would suggest the following
    more lightweight version, which creates and then nulls one button
    object per request. The use of an inner class allows the necessary
    communications between the action form and the button class. *

*public class AdminButtonForm
    extends ActionForm {
  protected CrackWillowButton button;
  protected String command;

  public CrackWillowButton getButton() {
    if(button == null) {
      this.button = new CrackWillowButton();
    }
    return button;
  }

  public String getCommand() {
    String hold = command;
    command = null;
    return hold;
  }

  public void setCommand(String command) {
    this.command = command;
  }

  public void reset() {
    button = null;
  }

  public class CrackWillowButton {
    private Integer x, y;
    public static final String CREATE   = "create";
    public static final String RETRIEVE = "retrieve";
    public static final String UPDATE   = "update";
    public static final String DELETE   = "delete";
    public static final String SUBMIT   = "submit";

    public CrackWillowButton() {
    }

    public CrackWillowButton getCreate()    {
      setCommand(this.CREATE);
      return button;
    }

    public CrackWillowButton getRetrieve()    {
      setCommand(this.RETRIEVE);
      return button;
    }

    public CrackWillowButton getUpdate()     {
      setCommand(this.UPDATE);
      return button;
    }

    public CrackWillowButton getDelete() {
      setCommand(this.DELETE);
      return button;
    }

    public CrackWillowButton getSubmit() {
      setCommand(this.SUBMIT);
      return button;
    }

    public void setX(Integer x) {
      if(y != null) {
        reset();
      } else {
        this.x = x;
      }
    }

    public void setY(Integer y) {
      if(x != null) {
        reset();
      } else {
        this.y = y;
      }
    }
  }
}
*

    *So, don't use buttons, but just mine the value of the [name].x
    request parameter. *

    *Michael McGrady Cap't of the Eh Team*

Anyway, looking forward to you thinking on this.

Michael

Rick Reumann wrote:

> Not sure which list this question/topic really belongs on so posting 
> to both. (I'm bringing it up on the dev list because I'm thinking 
> maybe the base MappingDispatchAction could/should be modified).
>
> Some design background. I like to keep related tasks belonging in one 
> Dispatch Action class (flavor to be discussed). This is a typical 
> approach, yet one of the problems is desided on the type of 
> DispatchAction ... keep it DispatchAction or use one of the subclasses 
> LookupDispatch or MappingDispatch.
>
> First off I really don't like the LookupDispatchAction. I've used it 
> extensively in a large application and it becomes a real pain. It 
> becomes really ugly to use when you start having some generic button 
> names that you reuse for different things. For example a changing 
> requirment was that we ended up having to use a button called "Ok" a 
> lot (I know stupid). So sometimes "Ok" would submit to the same 
> LookupDispatchAction but would need to access different methods. You 
> end up then having to create 'fake' button names in your resources 
> file just so the LookupDispatchAction can work correctly. Maintenance 
> of the LookupDispatch can be a pain also. Anyway...
>
> Until the MappingDispatchAction, I've been relatively content with 
> using a standard DispathAction. What I like about the 
> MappingDispatchAction is that it works really nicely for links - you 
> don't have to append a dispatch parameter name to the URL. It's also 
> nice for typical forms since you don't have to provide a hidden 
> dispatch parameter on the page.
>
> The only problem I'm running into it is when you have a form with more 
> than one button and each button should call a different dispatch 
> method. I haven't really figured out a good way to work this out with 
> the MappingDispatchAction.  I think trying to change the form's action 
> attribute using JavaScript will be ugly (assuming it can even be done, 
> I've never tried it). The only solution I can think of at the moment 
> would be to override the getMethodName method of MappingDispatch and 
> provide an extra mapping in your config where the parameter would 
> change to something like parameter="dispatchMethod"
>
> The overridden getMethodName might look like
>
> protected String getMethodName(
>         ActionMapping mapping,
>         ActionForm form,
>         HttpServletRequest request,
>         HttpServletResponse response,
>         String parameter)
>         throws Exception {
>     
>     if( "dispatchMethod".equals( parameter ) {
>             parameter = request.getParameter(parameter);
>     }
>         return parameter
>     }
>
> This would allow you to use the MappingDispatchAction like a 
> DispatchActoin when needed. The only caveat is you would have to make 
> sure the if statement in the above is what you wanted. (Probably 
> better to pull the parameter name "dispatchMethod" from a properties 
> file or constants class).
>
> Maybe there is a much better way to accomplish what I'm concerned with?
>



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org