2 Replies Latest reply on Jul 5, 2007 4:11 AM by Martin Makundi

    New to seam: How to choose proper context and achieve extern

    Martin Makundi Newbie

      Hi!

      Here is what I am trying to do:
      1. I need a page that loads its dataTable contents from db fresh every time I access the page.
      2. The items in the dataTable need to be clickable and bookmarkable in the future; this is why s:link was chosen. According to my experience, @Scope(PAGE) does not cut it with <s:link> elements, as the parameters are passed on as null.
      3. My business items allow clicking a link, but instead of directly linking the user to the external url I want to record the click-count first. So intuitively I thought I could just return the url from the click-counting action.

      The solutions I have tried are the following:
      1. Page scope seems to have the right idea: the dataTable contents are refreshed from db each time the page is refreshed. However, page context seem to have problems with requirement 2 -- or am I doing something else wrong?
      2. If I use Session scope, the <s:link> works fine and passes the actual objects as parameters to the desired method recordLinkClickAndRedirect(). However, with Session scope the dataTable does not get fresh data in a new page-refresh, because the session is still alive. I can actually make this happen by binding the @Destroy and @Remove annotations to my recordLinkClickAndRedirect() method, but it seams like a hack and I would rather not do that if there is a better way.
      3. I have not found a way to redirect from within my recordLinkClickAndRedirect() method, but intuitively it seems like there should be a way as this is how navigation can normally be affected.

      Here are my code snipplets:

      ::: from items.xhtml

      <!-- content -->
      <ui:define name="content">


      <h1>Latest business items</h1>

      <h:outputText value="No items found on this round. Please refresh page to check again!"
      rendered="#{businessItems == null or businessItems.rowCount==0}" />
      <h:dataTable var="businessItem" value="#{businessItems}"
      rendered="#{businessItems.rowCount>0}">
      <h:column>
      #{businessItem.description}
      <s:link value="#{businessItem.externalLinkURL}"
      action="#{itemViewer.recordLinkClickAndRedirect(businessItem)}" />
      </h:column>
      </h:dataTable>

      </ui:define>

      ::: from ItemViewer.java

      @Stateless
      @Scope(ScopeType.PAGE)
      @Name("itemViewer")
      public class ItemViewer implements LocalInterface {
      @PersistenceContext
      private EntityManager entityManager;

      @DataModel
      @SuppressWarnings("unused")
      private List businessItems;

      /**
      * This method TODO
      *
      */
      @Factory("businessItems")
      @SuppressWarnings("unchecked")
      public void getFreshBusinessItems() {
      businessItems = (List) entityManager
      .createQuery("select b from businessItem b");
      }

      /**
      * This method records that the link has been clicked and redirects the
      * browser to the specific link.
      *
      * @param businessItem
      * @return
      */
      public String recordLinkClickAndRedirect(BusinessItem businessItem) {
      businessItem.incrementClicks();
      return businessItem.getExternalLinkURL();
      }

      /**
      * This method is required by some scopes, e.g., Session scope.
      */
      // @Destroy
      // @Remove
      public void destroyAndRemove() {
      // n.a.
      }
      }