You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Jörn Zaefferer <jo...@googlemail.com> on 2007/02/25 11:57:22 UTC

Screwed up JSF lifecycle/component tree when using portlet2portlet communication

Hi myfacers,

I'm working on an application that is running on WebSphere Portal 5.1. I've
managed to exchange the IBM/Sun JSF implementation (and portlet bridge) with
MyFaces and Facelets, but one particular problem persists, caused by the
communication from portlet to portlet. It doesn't even matter if I use IBMs
"portlet wiring" (which doesn't work with MyFaces at all) or via the portlet
session in application scope (which is nothing more then the normal
HTTPSession).

So far IBM couldn't help at all, so maybe there is a MyFaces specific fix
for this. Or a generic JSF fix that I don't yet, which is quite likely.

Ok, on to the actual problem:

   1. I select an item in the first portlet, it is then opened in the
   second
   2. I edit some fields, causing validation errors when pressing Save
   3. I select a different item in the first portlet, it is displayed in
   the second, but the errors are still there


   1. Same steps as 1. and 2. above, but now I select Cancel
   (commandButton with immediate="true")
   2. I select a different item in the first portlet, it is displayed in
   the second, but:
   Only those fields that were empty after causing the validation error
   are now filled correctly, other fields still have the old value, though the
   underlying object has defnitely the correct data; The old data must come
   somewhere from the component tree

Our attemtps so far to clear the values from the component tree were
unsuccesful: I tried creating a new UIViewRoot (copying the RendererType
from the old one) and setting it as the new viewroot. A colleague tried to
set all submitted values in the tree to null, which didn't help either.

As IBMs porlet wiring doesn't work with MyFaces, I describe how I
implemented the communication via the application session:

   1. The first portlet sets an object to the portlet session in
   appliction scope in an action listener:
   public void selectMeeting(ActionEvent e) {
       DtreeNavEntry entry = entry(e);
       FacesUtil.saveApplicationSessionObject("Meeting", entry);
   }
   FacesUtil encapsulates some of the noisy JSF API calls, no magic there
   2. The other side is a bit more complicated:
      1. There is a PhaseListener registered in the
faces-config.xmlcalled PortletLifecycle
      2. This class manages a list of PhaseListeners, stored in the
      PortletSession, therefore each portlet can register one or more
      PhaseListeners that are only executed for that portlet (at least
that is how
      I'd like it to behave, but that isn't the problem here)
      3. The controller used in the second portlet registers a
      PhaseListener at this PortletLifecycle, adding a callback that
is executed
      before the RENDER_RESPONSE phase
      4. The callback checks if there is an object in the portlet
      session in application scope and if there is any, it removes it
      5. If there is an object, it does something with it, displaying
      the correct view (via fc.getViewRoot().setViewRoot(...) for the
      type of object (here: meetings, agenda items and activities)

Maybe someone on this list had already a similar problem and can provide a
hint for a solution. Let me know if it would help to post the code of the
controllers and the PortletLifecycle.

Any help is highly appreciated, thanks!

Regards
Jörn Zaefferer