3 Replies Latest reply on Mar 2, 2008 1:59 AM by Kariem Hussein

    Programmatically update conversation ?

    Kariem Hussein Newbie

      I have the following problem.


      One of my pages should be accessible by administrators and normal viewers. Administrators may edit information while viewers have read only access to a room.


      By entering the room's page, a new conversation is opened, and the room is put into a conversation scoped context variable to be accessible from sub-pages. It is not necessary to in/out-ject the room for all the sub-pages.


      This is great for administrators, as they can change multiple rooms simultaneously or even switch between rooms while being edited. In addition, the actions and pages are quite slim.


      The problem starts as soon as a user enters the room, while an administrator is editing. Updates to the room (such as closing it, in order to make it inaccessible) are visible to the user only after his transaction has ended and has been restarted.


      My question: is there a way to update the conversation or at least some context variables from outside the transaction/conversation?

        • 1. Re: Programmatically update conversation ?
          Pawel Wrzeszcz Novice

          There's certainly a way to access the conversations in your app. Have a look at built-in Seam component called conversationList. I'm not sure about the context variables.


          -P

          • 2. Re: Programmatically update conversation ?
            Kariem Hussein Newbie

            Thank you for the reply, Pawel.


            I can access the conversation easily from within my actions using Conversation.instance(). The problem is that I do not see a way of updating it, or any context variables within.


            It is possible to just leave or end the conversation (programmatically, via annotations or from within the view), but I would subsequently have to redirect to the page where the conversation started in order to retain all information needed to render the page.


            Am I doing something wrong?


            I wanted to reuse the same pages for administrators and users, but do something like a refresh on the user's conversation.

            • 3. Re: Programmatically update conversation ?
              Kariem Hussein Newbie

              I have found a way without rewriting the pages or the underlying actions. It seems like a hack, but I hope I can get feedback from the experts here, on how to do it the right way. At least it works for me.


              An additional method in my action class (I will call it action below):


              public void releaseConversation() {
                Conversation.instance().leave();
                env = null; // avoid re-injection
              }



              env is my conversation-scoped variable which should not be injected again.


              The conversation is initialized during (or better around?) the view method in the same class. In there I set a field (conversationRunning) that is used to determine whether the conversation has to be refreshed.


              @Begin(join = true)
              public void view(Integer id) {
                … // check id
                if (env != null) {
                  // already loaded or in admin conversation, where it is always loaded
                  conversationRunning = true;
                  return;
                }
                … // load and outject env
              }



              To wire this up, my xxx.page.xml has the following contents:


              <page …
                  action="#{action.view(id)}">
              
                <!-- conditional conversation release for non-admins -->
                <action execute="#{action.releaseConversation}" if="#{!s:hasPermission('env', 'admin', null) and action.conversationRunning}"/>
              
                <navigation from-action="#{action.releaseConversation}" >
                  <!-- redirect to same view and end currently running conversation -->
                  <end-conversation before-redirect="true"/>
                  <redirect view-id="/view/mypage.xhtml"/>
                </navigation>
                …
              </page>



              As you can see, after leaving the conversation during action.releaseConversation(), I redirect to the same view from within the page action. This method is only called, if an appropriate field is set on my action class.


              Just another note: it does not work with Conversation.instance().end() from my releaseConversation method. A similar behavior was also discussed in this forum.


              I hope I could explain my problem and the solution and would be happy if this can help someone. It would also be nice, if someone could tell me whether this is the right way, because it seems strange and I had quite a few problems on the way.