13 Replies Latest reply on Nov 30, 2006 10:37 AM by toni

    Understanding Conversations

    toni

      Hi Gavin,

      I wrote a short but interesting example to help me understand how conversations work in Seam. I think it's good for beginners - maybe you want to include something similar into the examples?

      The app consists of only one JSP page, which allows the user to start and end a conversation in several ways (nested, joined etc) in combination with a JavaBean called "CounterActions". The JSP page also displays all the conversations in progress.

      Then there is a Counter JavaBean, which can be incremented. It gets put into every new conversation which starts. Another JavaBean called CounterCount keeps track of the total numbers of counters, which currently exist.

      There are two questions I have from playing around with the application:

      1. Why ist the @Destroy method of the "Counter" JavaBean called
      twice?

      2. The conversation list is not displayed correctly. I checked this out using the debug.seam page. How come?

      Here are all the parts, which can be copied into any webapp. If somebody else feels to try this out, I would appreciate it. I think it's an iteresting way of teaching yourself how conversations really work and how they scope.

      faces-config.xml
      --------------------
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE faces-config
      PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
      "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
      <faces-config>

      <navigation-rule>
      <navigation-case>
      <from-outcome>displayCounter</from-outcome>
      <to-view-id>/displayCounter.jsp</to-view-id>
      </navigation-case>
      </navigation-rule>

      <!-- Phase listener needed for all Seam applications -->


      <phase-listener>org.jboss.seam.jsf.SeamPhaseListener</phase-listener>


      </faces-config>

      pages.xml
      -------------

      <page view-id="/displayCounter.jsp" timeout="300000">
      My Counter: #{counter.text}




      displayCounter.jsp
      ----------------------------
      <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
      <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
      <%@ taglib uri="http://jboss.com/products/seam/taglib" prefix="s" %>



      Current Counter


      <f:view>

      <h:outputText value="Counter ID: #{counter.thisCountersId}"/>
      <h:outputText value="Value: #{counter.value}"/>

      <s:link action="#{counterActions.increment}" value="Increase Counter"/>
      <s:link action="#{counterActions.startConversation}" value="Start Conversation"/>
      <s:link action="#{counterActions.startNestedConversation}" value="Nested"/>
      <s:link action="#{counterActions.joinConversation}" value="Join"/>
      <s:link action="#{counterActions.endConversation}" value="End It"/>
      <h:outputText value="Number of Counters: #{counterCount.currentNumberOfCounters}"/>

      <h:form>
      <h:dataTable value="#{conversationList}" var="entry" rendered="#{not empty conversationList}">
      <h:column>
      <f:facet name="header">
      <h:outputText value="Select Conversation"/>
      </f:facet>
      <h:commandLink action="#{entry.select}" value="#{entry.description}"/>
      </h:column>

      <h:column>
      <f:facet name="header">
      <h:outputText value="First / Last"/>
      </f:facet>
      <h:outputText value="#{entry.startDatetime}">
      <f:convertDateTime type="time" pattern="hh:mm a"/>
      </h:outputText>
      <h:outputText value=" - "/>
      <h:outputText value="#{entry.lastDatetime}">
      <f:convertDateTime type="time" pattern="hh:mm a"/>
      </h:outputText>
      </h:column>

      <h:column>
      <f:facet name="header">
      <h:outputText value="Action"/>
      </f:facet>
      <h:commandButton action="#{entry.select}" value="Switch"/>
      <h:commandButton action="#{entry.destroy}" value="Destroy"/>
      </h:column>

      </h:dataTable>
      </h:form>

      </f:view>



      Counter.java
      ----------------
      @Name("counter")
      @Scope(ScopeType.EVENT)

      public class Counter
      {
      @In
      CounterCount counterCount;

      int thisCountersId = -1;

      int value = 0;
      int destroyCount = 0;

      public Counter()
      {
      super();
      if (counterCount == null)
      counterCount = (CounterCount) Contexts.getApplicationContext().get("counterCount");
      if (counterCount == null)
      Contexts.getApplicationContext().set("counterCount", counterCount = new CounterCount());

      counterCreationOccurred();
      }

      @Create
      public void counterCreationOccurred()
      {
      if (thisCountersId == -1)
      {
      counterCount.increment();
      thisCountersId = counterCount.getTotalCountersEverCreated();
      }
      }

      @Destroy
      public void destroy()
      {
      if (thisCountersId != -1)
      {
      counterCount.decrement();
      destroyCount++;
      thisCountersId = -1;
      }
      }

      public int getValue()
      {
      return value;
      }

      public void setValue(int value)
      {
      this.value = value;
      }

      public void increment()
      {
      value++;
      }

      public int getThisCountersId()
      {
      return thisCountersId;
      }

      public void setThisCountersId(int thisCountersId)
      {
      //this.thisCountersId = thisCountersId;
      }

      public String getText()
      {
      return "Counter ID:" + thisCountersId + " Value: " + value;
      }

      public void setText()
      {
      }
      }

      CounterCount.java
      ------------------------
      @Name("counterCount")
      @Scope(ScopeType.APPLICATION)

      public class CounterCount
      {
      int currentNumberOfCounters = 0;
      int totalCountersEverCreated = 0;

      public int getCurrentNumberOfCounters()
      {
      return currentNumberOfCounters;
      }

      public void setCurrentNumberOfCounters(int currentNumberOfCounters)
      {
      this.currentNumberOfCounters = currentNumberOfCounters;
      }

      public void increment()
      {
      currentNumberOfCounters += 1;
      totalCountersEverCreated += 1;
      }

      public void decrement()
      {
      currentNumberOfCounters -= 1;
      }

      public int getTotalCountersEverCreated()
      {
      return totalCountersEverCreated;
      }

      public void setTotalCountersEverCreated(int totalCountersEverCreated)
      {
      this.totalCountersEverCreated = totalCountersEverCreated;
      }
      }

      CounterActions.java
      --------------------------
      @Name("counterActions")
      @Scope(ScopeType.EVENT)

      public class CounterActions
      {
      @In(required=false) @Out(scope=ScopeType.CONVERSATION, required=false)
      Counter counter;

      public String increment()
      {
      if (counter != null)
      counter.increment();
      return "displayCounter";
      }

      @Begin
      public String startConversation()
      {
      counter = new Counter();
      return "displayCounter";
      }

      @Begin(join = true)
      public String joinConversation()
      {
      counter = new Counter();
      return "displayCounter";
      }


      @Begin(nested = true)
      public String startNestedConversation()
      {
      counter = new Counter();
      return "displayCounter";
      }

      @End
      public String endConversation()
      {
      return "displayCounter";
      }
      }

        • 1. Re: Understanding Conversations
          toni

          Hi,

          since I haven't gotten any replies to my post I was wondering, if somebody could help me and try out the example above?

          I don't know why the conversation list is not being updated correctly or only after a reload of the page.

          I copied the code to display it from the issues example, so I think it should work.

          Hoping for some help,
          Toni

          • 2. Re: Understanding Conversations
            ellenzhao

            have you tried changing the <s:link> to <h:commandButton> or <h:commandLink>? I had experienced similar odds, but after changing the <s:link> to <h:commandButton>, my conversation state got updated correctly without an extra reload of the page.

            • 3. Re: Understanding Conversations
              ellenzhao

              And have you installed the seam redirect filter in the web.xml?

              • 4. Re: Understanding Conversations
                toni

                Hi Ellenzhao,

                thanks for the feedback. I don't have it installed, but I'm not using any redirects in the example.

                The part in the jsp file, which displays the conversations was taken from the issues example, which also does not use the redirect filter either.. I think.

                Why don't you try the example. It takes 4 minutes to integrate it into any existing application and try it out?

                Toni

                • 5. Re: Understanding Conversations
                  ellenzhao

                  are you sure the pages.xml above is not missing something? The page tag is not closed and what is My Counter: #{counter.text} ?

                  • 6. Re: Understanding Conversations
                    toni

                    This was a copy and paste error. The #{counter.text} will call the following function in the "Counter" JavaBean.

                    public String getText()
                    {
                    return "Counter ID:" + thisCountersId + " Value: " + value;
                    }

                    It is needed in order for the conversationsList object to work. I think it said somewhere, that you have to set the description. Here once again the complete pages.xml


                    <page view-id="/displayCounter.jsp" timeout="300000">
                    My Counter: #{counter.text}

                    • 7. Re: Understanding Conversations

                      That is the name of the page to be displayed in the conversationList. Without it, the page won't show up in the conversationList.

                      Everything in this example looks fine. As a sanity check, I copied the java code into one of my apps and it worked exactly as expected. I recommend comparing your configuration to the sample applications and looking for differences. You might also start with one of the sample apps and test your code in that environment. Whatever is wrong with your setup should pop up.

                      • 8. Re: Understanding Conversations
                        toni

                        Sorry I don't know why this happens. Even though I copy the whole pages.xml in, when I click on preview the lower half gets cut off.

                        But trust me the closing tags exist.

                        • 9. Re: Understanding Conversations
                          toni

                          Hi Norman,

                          thanks a lot for trying it out. That's why I asked - it all seems right.

                          However, I have to reload the page, before the table actually reflects the state of the actual context.

                          I cloned the registration app and copied all the important stuff from the issues app into it. I will have a close look and compare all the descriptors.


                          • 10. Re: Understanding Conversations
                            toni

                            Hi Norman,

                            I checked all my xml descriptors. Everything looks ok.

                            What version of seam and jboss are you using?

                            Could you do me a favour and try to reproduce the error:

                            1. Create 10 nested conversations by clicking 10 times on the "Nested" link.
                            2. Switch to converstion with counter id 5
                            3. End the conversation by clicking the "End" link

                            Now only the conversation with counter 5 disappears, even though all counters with id's greater or equal than 5 should disappear.

                            If I reload the page, then everything is displayed correctly.

                            • 11. Re: Understanding Conversations

                              Try replacing the conversation description with the conversation id, and I think you'll see a very different story. I just noticed that there IS a seam bug here in reporting the conversation description (for the current conversation only) when ending a conversation. I'll open a JIRA issue for this shortly.

                              • 12. Re: Understanding Conversations

                                Sorry for the delay. I reported the only Seam issue I could identify here: http://jira.jboss.com/jira/browse/JBSEAM-541

                                • 13. Re: Understanding Conversations
                                  toni

                                  Thanks ... I might have found another bug, even though I'm not sure. See:
                                  http://www.jboss.com/index.html?module=bb&op=viewtopic&t=96021