You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Martin Bosak (JIRA)" <in...@incubator.apache.org> on 2005/03/31 20:25:16 UTC

[jira] Commented: (MYFACES-20) JSCookMenus cause duplicated execution of MethodBinding

     [ http://issues.apache.org/jira/browse/MYFACES-20?page=comments#action_61903 ]
     
Martin Bosak commented on MYFACES-20:
-------------------------------------

I have a possible fix/workaround for this.  Basically, I add the id of the jsCookMenu component to the jscook_action string sent in the request.  Then, in the decode method, before creating the MethodBinding from the returned parameter, I pull the id from the string and compare it to the component we are decoding for.  If they don't match, I return.  Otherwise, the MethodBinding for the action is created and invoked.

I also added the ability to set a value on a bean before the action is invoked.  I had to dynamically build a menu based upon the configured locales (to allow the user to select the language).  The original code didn't have any way to identify which menu item was selected.  My change was:  1)  When creating the UINavigationMenuItem for the specific language, I would add a value binding to the binding map under a key of "NavMenuItemValue".  2)  Modified the HtmlJSCookMenuRenderer to pass the current child list encodeNavigationMenuItems method.  When an action is configured, I also check the value binding map for the corresponding UINavigationMenuItem to see if a value binding has been added.  If so, I add the value binding expression along with the NavigationMenuItem value to the jscook_action parameter.  3)  In the corresponding decode, if a binding is detected, it is invoked before the action method is invoked.

This is will only work for programatcally constructed menu items; but a more general mechanism could be developed for specification via a tag.


Here is the CVS diff:

cvs diff HtmlJSCookMenuRenderer.java (in directory C:\CVSRepositories\Apache\incubator-myfaces\src\components\org\apache\myfaces\custom\navmenu\jscookmenu\)
Index: HtmlJSCookMenuRenderer.java
===================================================================
RCS file: /home/cvspublic/incubator-myfaces/src/components/org/apache/myfaces/custom/navmenu/jscookmenu/HtmlJSCookMenuRenderer.java,v
retrieving revision 1.12
diff -r1.12 HtmlJSCookMenuRenderer.java
20a21
> import org.apache.myfaces.custom.navmenu.UINavigationMenuItem;
31a33
> import javax.faces.el.ValueBinding;
93a96,103
>             String compId = component.getId();
>             int idx = actionParam.indexOf(':');
>             String actionId = actionParam.substring(0, idx);
>             if (! compId.equals(actionId)) {
>                 return;
>             }
>             actionParam = actionParam.substring(idx + 1);
>             actionParam = decodeValueBinding(actionParam, context);
108a119,142
>     private String decodeValueBinding(String actionParam, FacesContext context) 
>     {
>         int idx = actionParam.indexOf(";#{"); 
>         if (idx == -1) {
>             return actionParam;
>         }
>         
>         String newActionParam = actionParam.substring(0, idx);
>         String vbParam = actionParam.substring(idx + 1);
>         
>         idx = vbParam.indexOf('=');
>         if (idx == -1) {
>             return newActionParam;
>         }
>         String vbExpressionString = vbParam.substring(0, idx);
>         String vbValue = vbParam.substring(idx + 1);
>         
>         ValueBinding vb = 
>             context.getApplication().createValueBinding(vbExpressionString);        
>         vb.setValue(context, vbValue);
>         
>         return newActionParam;
>     }
>     
120a155
>             List uiNavMenuItemList = component.getChildren();
124a160,161
>             String myId = component.getId();
>             
130c167,169
<                                       (NavigationMenuItem[]) list.toArray(new NavigationMenuItem[list.size()]));
---
>                                       (NavigationMenuItem[]) list.toArray(new NavigationMenuItem[list.size()]),
>                                       uiNavMenuItemList,
>                                       myId);
139c178,180
<                                            NavigationMenuItem[] items)
---
>                                            NavigationMenuItem[] items,
>                                            List uiNavMenuItemList,
>                                            String menuId)
144a186,196
>             Object tempObj = null;
>             UINavigationMenuItem uiNavMenuItem = null;
>             try {
>                 tempObj = uiNavMenuItemList.get(i);
>             } catch (IndexOutOfBoundsException  e) {
>             }
>             if (tempObj != null) {
>                 if (tempObj instanceof UINavigationMenuItem) {
>                     uiNavMenuItem = (UINavigationMenuItem) tempObj;
>                 }
>             }
177a230,231
>                 writer.write(menuId);
>                 writer.write(':');
178a233,235
>                 if (uiNavMenuItem != null) {
>                     encodeValueBinding(writer, uiNavMenuItem, item);
>                 }
193c250,251
<                     encodeNavigationMenuItems(context, writer, menuItems);
---
>                     encodeNavigationMenuItems(context, writer, menuItems, 
>                             uiNavMenuItem.getChildren(), menuId);
199a258,279
>     private void encodeValueBinding(ResponseWriter writer, UINavigationMenuItem uiNavMenuItem, 
>             NavigationMenuItem item) throws IOException 
>     {
>         ValueBinding vb = uiNavMenuItem.getValueBinding("NavMenuItemValue");
>         if (vb == null) {
>             return;
>         }
>         String vbExpression = vb.getExpressionString();
>         if (vbExpression == null) {
>             return;
>         }
>         Object tempObj = item.getValue();
>         if (tempObj == null) {
>             return;
>         }
>         
>         writer.write(";");
>         writer.write(vbExpression);
>         writer.write("=");
>         writer.write(tempObj.toString());
>     }
>     



> JSCookMenus cause duplicated execution of MethodBinding
> -------------------------------------------------------
>
>          Key: MYFACES-20
>          URL: http://issues.apache.org/jira/browse/MYFACES-20
>      Project: MyFaces
>         Type: Bug
>     Versions: 1.0.7 beta
>  Environment: JBoss 4.0
>     Reporter: 
>     Assignee: Thomas Spiegl

>
> I have on my page different JSCookMenus. Problem is, that when I select an MenuItem to execute a MethodBinding, this Methodbinding is executed as often as I have JSCookMenus on my page.
> I assume, that in the background only an action is set and not the context of the menu. This would cause for each "decode" of the HtmlJSCookMenu an ActionEvent to be queued.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira