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

    Understanding Conversations

    Toni Beckman Novice

      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";
      }
      }