Fwd: Experience with developing web app. based on MyFaces

2005-08-26 Thread mirek novak
Hi,
 I've been working on an application based on MyFaces 1.0.8. Now, we
are moving to MyFaces 1.0.9 and I would like to discuss discovered
issues and some ideas (not only related to MyFaces but to JSF in
general).


 AliasBean

   * This is a pretty useful component and I'm glad that MyFaces contains it!
   * There were a few bugs in this component in MyFaces 1.0.8
(processSaveState, queueEvent) but now they are fixed (1.0.9) - great

Table

   * This is one of the most used components
   * It's definitely better than standard table (sorting support,
scroller, …) BUT:
  * Suppose this (selecting a row while model has been
concurrently modified by a different user):

 1) Your table has 3 rows and you display a check box for each
row so that user can select a row

 2) User selects first row and submits but another user has
concurrently deleted first row. So, model has now only 2 rows.

 3) Submitted value (selected checkbox of the first row) will
be applied to the first row of the model. So, actually the second row
is selected :-(. (we've developed a quite simple solution, so if you
are interested, let me know - and we definitely do not serialize whole
model of the table!)

  * It's a common case that table rows have checkboxes and can be
selected. So, we have to provide (for most of the tables) model where
each row is wrapped in an extra class that has selected property -
and that's tedious.

DataScroller
=
   * We've discovered following issue: uiData.setFirst(someNewValue)
is used within the =decode= method of the HtmlDataScrollerRenderer -
it is too early to modify uiData within =apply request values phase=.
  * If some rows of the table were modified too, they will be
applied to wrong table rows :-( (because setFirst has already been
called and table contains different rows now)
   * Our solution: DataScrollerRenderer fires an even that uiData
should be updated, and they are updated later in =update model values=
phase (just after model has been updated)

Backing Bean's State, HttpSession, Concurrent Access within a Session
===
In my view, a reasonable web application should fulfill following requirements:
   * users can use browser's navigation buttons (back, forward, reload)
   * users can use an application from multiple browser tabs (tabs
share the same session)

Although these requirements look simple and unimportant, they present
serious problems and have serious consequences on the whole
architecture of an application.

   * navigation buttons
  * We use redirects. So, user can use the back button even when
he's moved to a next page via HTTP POST
  * We use javax.faces.STATE_SAVING_METHOD=client. So, even if
user has pressed the back button 10 times, a proper view will be
restored when he submits form (or clicks link) on the old page (if
state saving=server, this would obviously not work - you would have to
click twice to perform an action :-)).
  * But who/when/how will store state of backing beans? - note
that if you not store the state of your backing beans on a client,
your application will not work. Suppose this:

 1) Your page displays a category (it has name, description
and sub-categories)

 2) User selected category A and it is stored in a property
=currentCategory= in your backing bean

 3) User selected category B (sub-category of A), so
=currentCategory= is now B

 4) User uses browser's back button, so he can see detail of category A

 5) User edits description of the category (A) and submits the page

 6) Description of category B will be updated because
=currentCategory= is still B :-(

   * Solution: a component (saveState) that accepts a value binding
and saves the value within its state. E.g. y:saveState
value=#{myConroller.pageState}/

   * tabbed browsing
  * Any session scope backing bean is a potential race-condition
  * Moreover, if your data like currentItem, MyPageConroller
have session scope, actions performed in one tab may influence
behavior of the other tab


Error Handling
===
   * We created a special component similar to the Buffer component.
We render a sub-tree of this component into the buffer and if and
exception is thrown while processing the sub-tree, we render the
exception. (in addition, we had to wrap ActionListener,
HtmlDataTablePhaseListener, …).

   * It would be nice to see an errorHandling component in next
MyFaces distribution.

I hope that you will find some info from this mail useful and intelligible.

Best regards,

MN.


Re: Experience with developing web app. based on MyFaces

2005-08-26 Thread Enrique Medina
It would be great if you could copy all this to the Wiki ;-)

http://wiki.apache.org/myfaces/2005/8/26, mirek novak [EMAIL PROTECTED]:
Hi, I've been working on an application based on MyFaces 1.0.8. Now, weare moving to MyFaces 
1.0.9 and I would like to discuss discoveredissues and some ideas (not only related to MyFaces but to JSF ingeneral). AliasBean * This is a pretty useful component and I'm glad that MyFaces contains it!
 * There were a few bugs in this component in MyFaces 1.0.8(processSaveState, queueEvent) but now they are fixed (1.0.9) - greatTable * This is one of the most used components * It's definitely better than standard table (sorting support,
scroller, …) BUT:* Suppose this (selecting a row while model has beenconcurrently modified by a different user): 1) Your table has 3 rows and you display a check box for eachrow so that user can select a row
 2) User selects first row and submits but another user hasconcurrently deleted first row. So, model has now only 2 rows. 3) Submitted value (selected checkbox of the first row) will
be applied to the first row of the model. So, actually the second rowis selected :-(. (we've developed a quite simple solution, so if youare interested, let me know - and we definitely do not serialize wholemodel of the table!)
* It's a common case that table rows have checkboxes and can beselected. So, we have to provide (for most of the tables) model whereeach row is wrapped in an extra class that has selected property -
and that's tedious.DataScroller= * We've discovered following issue: uiData.setFirst(someNewValue)is used within the =decode= method of the HtmlDataScrollerRenderer -it is too early to modify uiData within =apply request values phase=.
* If some rows of the table were modified too, they will beapplied to wrong table rows :-( (because setFirst has already beencalled and table contains different rows now) * Our solution: DataScrollerRenderer fires an even that uiData
should be updated, and they are updated later in =update model values=phase (just after model has been updated)Backing Bean's State, HttpSession, Concurrent Access within a Session===
In my view, a reasonable web application should fulfill following requirements: * users can use browser's navigation buttons (back, forward, reload) * users can use an application from multiple browser tabs (tabs
share the same session)Although these requirements look simple and unimportant, they presentserious problems and have serious consequences on the wholearchitecture of an application. * navigation buttons
* We use redirects. So, user can use the back button even whenhe's moved to a next page via HTTP POST* We use javax.faces.STATE_SAVING_METHOD=client. So, even ifuser has pressed the back button 10 times, a proper view will be
restored when he submits form (or clicks link) on the old page (ifstate saving=server, this would obviously not work - you would have toclick twice to perform an action :-)).* But who/when/how will store state of backing beans? - note
that if you not store the state of your backing beans on a client,your application will not work. Suppose this: 1) Your page displays a category (it has name, descriptionand sub-categories)
 2) User selected category A and it is stored in a property=currentCategory= in your backing bean 3) User selected category B (sub-category of A), so=currentCategory= is now B 4) User uses browser's back button, so he can see detail of category A
 5) User edits description of the category (A) and submits the page 6) Description of category B will be updated because=currentCategory= is still B :-( * Solution: a component (saveState) that accepts a value binding
and saves the value within its state. E.g. y:saveStatevalue=#{myConroller.pageState}/ * tabbed browsing* Any session scope backing bean is a potential race-condition
* Moreover, if your data like currentItem, MyPageConrollerhave session scope, actions performed in one tab may influencebehavior of the other tabError Handling===
 * We created a special component similar to the Buffer component.We render a sub-tree of this component into the buffer and if andexception is thrown while processing the sub-tree, we render theexception. (in addition, we had to wrap ActionListener,
HtmlDataTablePhaseListener, …). * It would be nice to see an errorHandling component in nextMyFaces distribution.I hope that you will find some info from this mail useful and intelligible.
Best regards,MN.


Re: Experience with developing web app. based on MyFaces

2005-08-26 Thread Sean Schofield
Better take a look at the latest nightly build.  I suspect several of
your issues have been resolved already in the upcoming 1.0.10 release.
 We're probably 2-3 weeks away from the release and now is the time to
let us know about bugs.  (Feature requests can wait until future
relelases but bugs should be addressed *now*.)

sean

On 8/26/05, Enrique Medina [EMAIL PROTECTED] wrote:
 It would be great if you could copy all this to the Wiki ;-)
  
  http://wiki.apache.org/myfaces/
 
 2005/8/26, mirek novak [EMAIL PROTECTED]: 
  Hi,
  I've been working on an application based on MyFaces 1.0.8. Now, we
  are moving to MyFaces 1.0.9 and I would like to discuss discovered
  issues and some ideas (not only related to MyFaces but to JSF in
  general).
  
  
  AliasBean
  
 * This is a pretty useful component and I'm glad that MyFaces contains
 it! 
 * There were a few bugs in this component in MyFaces 1.0.8
  (processSaveState, queueEvent) but now they are fixed (1.0.9) - great
  
  Table
  
 * This is one of the most used components
 * It's definitely better than standard table (sorting support, 
  scroller, …) BUT:
* Suppose this (selecting a row while model has been
  concurrently modified by a different user):
  
   1) Your table has 3 rows and you display a check box for each
  row so that user can select a row 
  
   2) User selects first row and submits but another user has
  concurrently deleted first row. So, model has now only 2 rows.
  
   3) Submitted value (selected checkbox of the first row) will
  be applied to the first row of the model. So, actually the second row
  is selected :-(. (we've developed a quite simple solution, so if you
  are interested, let me know - and we definitely do not serialize whole
  model of the table!) 
  
* It's a common case that table rows have checkboxes and can be
  selected. So, we have to provide (for most of the tables) model where
  each row is wrapped in an extra class that has selected property - 
  and that's tedious.
  
  DataScroller
  =
 * We've discovered following issue: uiData.setFirst(someNewValue)
  is used within the =decode= method of the HtmlDataScrollerRenderer -
  it is too early to modify uiData within =apply request values phase=. 
* If some rows of the table were modified too, they will be
  applied to wrong table rows :-( (because setFirst has already been
  called and table contains different rows now)
 * Our solution: DataScrollerRenderer fires an even that uiData 
  should be updated, and they are updated later in =update model values=
  phase (just after model has been updated)
  
  Backing Bean's State, HttpSession, Concurrent Access within a Session
  === 
  In my view, a reasonable web application should fulfill following
 requirements:
 * users can use browser's navigation buttons (back, forward, reload)
 * users can use an application from multiple browser tabs (tabs 
  share the same session)
  
  Although these requirements look simple and unimportant, they present
  serious problems and have serious consequences on the whole
  architecture of an application.
  
 * navigation buttons 
* We use redirects. So, user can use the back button even when
  he's moved to a next page via HTTP POST
* We use javax.faces.STATE_SAVING_METHOD=client.
 So, even if
  user has pressed the back button 10 times, a proper view will be 
  restored when he submits form (or clicks link) on the old page (if
  state saving=server, this would obviously not work - you would have to
  click twice to perform an action :-)).
* But who/when/how will store state of backing beans? - note 
  that if you not store the state of your backing beans on a client,
  your application will not work. Suppose this:
  
   1) Your page displays a category (it has name, description
  and sub-categories)
  
   2) User selected category A and it is stored in a property
  =currentCategory= in your backing bean
  
   3) User selected category B (sub-category of A), so
  =currentCategory= is now B
  
   4) User uses browser's back button, so he can see detail of
 category A 
  
   5) User edits description of the category (A) and submits the
 page
  
   6) Description of category B will be updated because
  =currentCategory= is still B :-(
  
 * Solution: a component (saveState) that accepts a value binding 
  and saves the value within its state. E.g. y:saveState
  value=#{myConroller.pageState}/
  
 * tabbed browsing
* Any session scope backing bean is a potential race-condition 
* Moreover, if your data like currentItem, MyPageConroller
  have session scope, actions performed in one tab may influence
  behavior of the other tab
  
  
  Error Handling
  === 
 * We created a special component similar to the Buffer component.
  We 

Re: Experience with developing web app. based on MyFaces

2005-08-26 Thread Mirek Novak
On 8/26/05, Enrique Medina [EMAIL PROTECTED] wrote:
 It would be great if you could copy all this to the Wiki ;-)
  
  http://wiki.apache.org/myfaces/

I'll take a look at it.

Yes, some issues have been already resolved - a few minutes after
sending this mail I've come across saveState component that works
*exactly* the same way as our component :-)

 
 2005/8/26, mirek novak [EMAIL PROTECTED]: 
  Hi,
  I've been working on an application based on MyFaces 1.0.8. Now, we
  are moving to MyFaces 1.0.9 and I would like to discuss discovered
  issues and some ideas (not only related to MyFaces but to JSF in
  general).
  
  
  AliasBean
  
 * This is a pretty useful component and I'm glad that MyFaces contains
 it! 
 * There were a few bugs in this component in MyFaces 1.0.8
  (processSaveState, queueEvent) but now they are fixed (1.0.9) - great
  
  Table
  
 * This is one of the most used components
 * It's definitely better than standard table (sorting support, 
  scroller, …) BUT:
* Suppose this (selecting a row while model has been
  concurrently modified by a different user):
  
   1) Your table has 3 rows and you display a check box for each
  row so that user can select a row 
  
   2) User selects first row and submits but another user has
  concurrently deleted first row. So, model has now only 2 rows.
  
   3) Submitted value (selected checkbox of the first row) will
  be applied to the first row of the model. So, actually the second row
  is selected :-(. (we've developed a quite simple solution, so if you
  are interested, let me know - and we definitely do not serialize whole
  model of the table!) 
  
* It's a common case that table rows have checkboxes and can be
  selected. So, we have to provide (for most of the tables) model where
  each row is wrapped in an extra class that has selected property - 
  and that's tedious.
  
  DataScroller
  =
 * We've discovered following issue: uiData.setFirst(someNewValue)
  is used within the =decode= method of the HtmlDataScrollerRenderer -
  it is too early to modify uiData within =apply request values phase=. 
* If some rows of the table were modified too, they will be
  applied to wrong table rows :-( (because setFirst has already been
  called and table contains different rows now)
 * Our solution: DataScrollerRenderer fires an even that uiData 
  should be updated, and they are updated later in =update model values=
  phase (just after model has been updated)
  
  Backing Bean's State, HttpSession, Concurrent Access within a Session
  === 
  In my view, a reasonable web application should fulfill following
 requirements:
 * users can use browser's navigation buttons (back, forward, reload)
 * users can use an application from multiple browser tabs (tabs 
  share the same session)
  
  Although these requirements look simple and unimportant, they present
  serious problems and have serious consequences on the whole
  architecture of an application.
  
 * navigation buttons 
* We use redirects. So, user can use the back button even when
  he's moved to a next page via HTTP POST
* We use javax.faces.STATE_SAVING_METHOD=client.
 So, even if
  user has pressed the back button 10 times, a proper view will be 
  restored when he submits form (or clicks link) on the old page (if
  state saving=server, this would obviously not work - you would have to
  click twice to perform an action :-)).
* But who/when/how will store state of backing beans? - note 
  that if you not store the state of your backing beans on a client,
  your application will not work. Suppose this:
  
   1) Your page displays a category (it has name, description
  and sub-categories)
  
   2) User selected category A and it is stored in a property
  =currentCategory= in your backing bean
  
   3) User selected category B (sub-category of A), so
  =currentCategory= is now B
  
   4) User uses browser's back button, so he can see detail of
 category A 
  
   5) User edits description of the category (A) and submits the
 page
  
   6) Description of category B will be updated because
  =currentCategory= is still B :-(
  
 * Solution: a component (saveState) that accepts a value binding 
  and saves the value within its state. E.g. y:saveState
  value=#{myConroller.pageState}/
  
 * tabbed browsing
* Any session scope backing bean is a potential race-condition 
* Moreover, if your data like currentItem, MyPageConroller
  have session scope, actions performed in one tab may influence
  behavior of the other tab
  
  
  Error Handling
  === 
 * We created a special component similar to the Buffer component.
  We render a sub-tree of this component into the buffer and if and
  exception is thrown while processing the sub-tree, we render