You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Gregg Leichtman <gs...@verizon.net> on 2009/12/15 14:49:51 UTC

Fwd: Re: [Trinidad] Cannot Add Item to SelectManyShuttle After Initial Rendering

I am moving this Trinidad thread to this list, since I wondered if the
dev team had any thoughts about this.

                      -=> Gregg <=-

> -------- Original Message --------
> Subject: 	Re: [Trinidad] Cannot Add Item to SelectManyShuttle After
> Initial Rendering
> Date: 	Fri, 11 Dec 2009 09:01:16 -0500
> From: 	Gregg Leichtman <gs...@verizon.net>
> Reply-To: 	MyFaces Discussion <us...@myfaces.apache.org>
> To: 	MyFaces Discussion <us...@myfaces.apache.org>
>
>
>
> I  commented out the code shown below and the round trip worked
> perfectly, so should I conclude that it is necessary to drop this check
> in order to meet the contract, since I don't believe that the client
> programmer should have to override a package private method in order to
> use the addItem function?
>
> I also noticed, by placing breakpoints in my bean, that the
> getSubmittedValue method of the shuttle renderer is, of course, called
> during the request parameter decoding stage before my bean's
> valueChanged method is ever invoked. In fact the only chance my bean's
> code ever gets to try and circumvent this problem is in a setter in my
> bean associated with the submit action. This setter does not, of course,
> get passed the valueChanged event and gets invoked prior to the
> getSubmittedValue decoding which does not seem to be the correct place
> to try and "fix" this problem. It seems to me that this check, although
> probably well-intentioned, assuming that it is there to prevent client
> programmer mistakes or overflow attacks, may need to be removed with a
> documented cavaet to the user of the shuttle that they should put in
> code to do said check AFTER the decoding stage. If this view is correct
> and assuming that the JSF standard is not violated, then possibly a
> method such as confirmValidSubmittedValue should be created such that
> the client programmer of the shuttle can override the method with any
> logic they need. The original logic in the parent method supplied by the
> toolkit would simply include the check logic below (altered accordingly
> to account for being executed in a stage following the decoding stage),
> but at the client programmer's discretion could, for example, include
> code to limit the number of additions within a given time window to help
> thwart an attack.
>
>   protected Object getSubmittedValue(
>     FacesContext context,
>     UIComponent  component,
>     String       clientId)
>   {
>     // Since we override getSubmittedValue() entirely,
>     // detect auto submit manually
>     detectAutoSubmit(context, component, clientId);
>
>     String trailingId = clientId + ":trailing:items";
>     String paramValue = (String) context.getExternalContext().
>                                 getRequestParameterMap().get(trailingId);
>     if ((paramValue == null) || "".equals(paramValue))
>       return new String[0];
>
>     List<String> list = new ArrayList<String>();
>     StringTokenizer tokenizer = new StringTokenizer(paramValue, ";");
>
>     // don't let the submitted list get any bigger than the number of
>     // total items in the shuttle
> //    int availableItems = SelectItemSupport.getSelectItemCount(component);
>     int numItems = 0;
>     while (tokenizer.hasMoreElements())
>     {
>       numItems++;
> //      if (numItems > availableItems)
> //      {
> //        _LOG.severe("SELECTED_SHUTTLE_ITEMS_EXCEEDED_TOTAL_NUMBER",clientId);
> //        return new String[0];
> //      }
>
>       list.add(tokenizer.nextToken());
>     }
>
>
>
>
> On 12/11/2009 05:16 AM, Rafa PĂ©rez wrote:
> > Maybe you can force an update of the SelectItems via PPR when the new item
> > is added. This way, you can handle this element at server side.
> >
> > HTH,
> >
> > -- Rafa
> >
> > On Fri, Dec 11, 2009 at 11:14 AM, Jakob Korherr <ja...@gmail.com>wrote:
> >
> >   
> >> Hi Gregg,
> >>
> >> The problem is, that the SelectItem, which you add via javascript, is not
> >> included in SelectItemSupport.getSelectItemCount(component).
> >>
> >> Looking at the code of shuttle.js, I found out that addItem() also adds the
> >> new item to a hidden field in the form with name clientId:items. So the
> >> server should know that you added the related item. However, I could not
> >> find the server side code, which does that.
> >>
> >> Maybe anyone else knows where this is accomplished.
> >>
> >> Regards,
> >>
> >> Jakob Korherr
> >>
> >> 2009/12/11 <gs...@verizon.net>
> >>
> >>     
> >>> I have a Select Many Ordered Shuttle working in a faces page. The tag
> >>> documentation contract for the shuttle states:
> >>>
> >>> ------------------------------------------
> >>>  -- JavaScript proxies --
> >>>
> >>> In some cases, developers will need to use JavaScript to manipulate or use
> >>> the contents of the lists.  This may be required as actions for the buttons
> >>> or icons in the shuttle footers or outside the shuttle all together. Thus, a
> >>> set of Javascript utility methods are available that operate on the
> >>> lists.
> >>     
> >>> These are located in the shuttle.js Javascript library, which is
> >>> automatically loaded if you use the shuttle.
> >>> These methods can be accessed by creating a ShuttleProxy instance based on
> >>> the shuttle client ID and form.
> >>>                // create the proxy object
> >>>                var proxy2 = new ShuttleProxy("testShuttle2","testForm2");
> >>     
> >>> Once the proxy is created, you can use it to gain information about the
> >>> lists or to manipulate the lists in the shuttle.  The proxy provides the
> >>> following functions:
> >>> ...
> >>> addItem(leadingList, index, text, value, description) : adds an item at the
> >>> given index to a list.  The item is added to the leading list if leadingList
> >>> is true, otherwise it is added to the trailing list. The index should be 0
> >>> based.  Thus, to insert an item at the end of a list, set index to
> >>> shuttleProxy.getItemCount(leadinglist).  The text parameter specifies the
> >>> display text for the item, while the value parameter specifies the value
> >>> that represents this item upon form submission. The description parameter
> >>> specifies a description of the item. The description parameter can be
> >>> omitted
> >>> ....
> >>>
> >>> -------------------------------------------
> >>>
> >>> I have written the JavaScript code to add an item to the shuttle and this
> >>> works at the client end; however, when I try and submit the shuttle lists,
> >>> the server end fails when it gets to class
> >>>       
> >> org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SelectManyShuttleRenderer
> >>     
> >>> when it is decoding the submitted list in method getSubmittedValue as shown
> >>> below:
> >>>
> >>>   protected Object getSubmittedValue(
> >>>     FacesContext context,
> >>>     UIComponent  component,
> >>>     String       clientId)
> >>>   {
> >>>     // Since we override getSubmittedValue() entirely,
> >>>     // detect auto submit manually
> >>>     detectAutoSubmit(context, component, clientId);
> >>>
> >>>     String trailingId = clientId + ":trailing:items";
> >>>     String paramValue = (String) context.getExternalContext().
> >>>                                 getRequestParameterMap().get(trailingId);
> >>>     if ((paramValue == null) || "".equals(paramValue))
> >>>       return new String[0];
> >>>
> >>>     List<String> list = new ArrayList<String>();
> >>>     StringTokenizer tokenizer = new StringTokenizer(paramValue, ";");
> >>>
> >>>     // don't let the submitted list get any bigger than the number of
> >>>     // total items in the shuttle
> >>>     int availableItems = SelectItemSupport.getSelectItemCount(component);
> >>>     int numItems = 0;
> >>>     while (tokenizer.hasMoreElements())
> >>>     {
> >>>       numItems++;
> >>>       if (numItems > availableItems)
> >>>       {
> >>>         _LOG.severe("SELECTED_SHUTTLE_ITEMS_EXCEEDED_TOTAL_NUMBER", clientId);
> >>>         return new String[0];
> >>>       }
> >>>       list.add(tokenizer.nextToken());
> >>>     }
> >>>     ...
> >>>
> >>> The check to confirm that the number of submitted items is not greater than
> >>> the original shuttle list already in existence at the server end, stops any
> >>> user from adding an additional item to the shuttle. I understand that this
> >>> may have been done to protect against an attack where someone sends in a
> >>> huge list of shuttle items, BUT this seems to be in direct conflict with the
> >>> shuttle contract above that states that I should be able to add one or more
> >>> items to a shuttle at the client end. I don't believe the intention was
> >>> simply to add items to the shuttle at the client end without submitting it.
> >>> I was unable to find any examples, working or otherwise, anywhere that
> >>> demonstrate said functionality.
> >>>
> >>> Given the above, if this getSubmittedValue code is correct and the addItem
> >>> contract is also correct, how does one add an item to an existing shuttle
> >>> AND submit it to the server?
> >>>
> >>>                                        -=> Gregg <=-
> >>>
> >>>
> >>>
> >>>       
> >>     
> >   
>
>
>
>