[jboss-user] [JBoss Seam] - Re: Seam application with tree on left and editor for select
christian.bauer@jboss.com
do-not-reply at jboss.com
Tue Oct 17 14:35:39 EDT 2006
Some code:
package auction.beans;
|
| import org.jboss.seam.annotations.*;
| import org.jboss.seam.annotations.datamodel.DataModel;
| import org.jboss.seam.annotations.datamodel.DataModelSelection;
| import org.jboss.seam.ScopeType;
| import org.hibernate.ejb.HibernateEntityManager;
|
| import javax.ejb.Stateful;
| import javax.ejb.Remove;
| import javax.persistence.EntityManager;
|
| import auction.model.Category;
| import auction.model.Item;
| import auction.dao.CategoryDAO;
| import auction.interceptors.LoggedIn;
|
| import java.util.*;
|
| /**
| * A conversational component for browsing the catalog.
| *
| * When the first variable for "catalog" has to be resolved, this component is
| * instantiated and a conversation begins. All root categories (with no parent)
| * of the catalog are loaded immediately and held during the conversation.
| *
| * When a category is selected, the selected value is passed into the method
| * setSelectedCategory(category) manually, this is the easiest way to get the
| * value of a click from a Trinidad tree JSF component.
| *
| * The item list is loaded when a category is selected and outjected into a
| * data model for display. When a user triggers an action in the data model's
| * table, the selectedItem of this conversation is set.
| *
| * The conversation ends usually by timeout or when it is destroyed
| * with one of Seams UI conversation management switchers/lists.
| *
| * @author Christian Bauer
| */
| @Name("catalog")
| @Scope(ScopeType.CONVERSATION) // Redundant, a SFSB is default in conversation context
|
| @LoggedIn // Wrap LoginInterceptor around every method call
|
| @Stateful
| public class CatalogBean implements Catalog {
|
| // We don't call the EntityManager directly in this bean (except to flush), only the DAOs.
| // But the DAOs are not always called in every method that does data access. For example,
| // when setSelectedCategory() is called, the categoryDAO is injected into this bean,
| // but the persistence context is not set on the categoryDAO (because no method is
| // called on the DAO, we just load a collection on-demand). So the persistence context
| // doesn't join the JTA transaction, which means it doesn't get flushed when
| // setSelectedCategory() returns (no synchronization registered). Short story: The
| // persistence context needs to be injected managed here, so that lazy loading works
| // properly in all methods of this stateful bean.
| @In(value = "caveatEmptorEM", create = true)
| private EntityManager em;
|
| // A stateless (yes, even for them create="true" is required) DAO component injected by Seam
| @In(create = true)
| private CategoryDAO categoryDAO;
|
| // This bean holds the root categories during a conversation
| private List<Category> rootCategories;
|
| // If present, Seam outjects this into the 'currentCategory' CONVERSATION variable
| @In(required = false)
| @Out(required = false, scope = ScopeType.CONVERSATION)
| private Category currentCategory;
|
| // Seam outjects this always to the 'itemList" CONVERSATION variable as a JSF DataModel
| @DataModel
| private List<Item> itemList;
|
| /**
| * Seam calls this when the Catalog bean is instantiated for a particular CONVERSATION.
| * Seam will start a long-running conversation when this method is called.
| */
| @Create
| @Begin(flushMode = FlushModeType.MANUAL)
| public void refreshRootCategories() {
| rootCategories = categoryDAO.findAll(true);
| }
|
| public List<Category> getRootCategories() {
| return rootCategories;
| }
|
| /**
| * Loads the selected category's items into a data model that is then outjected.
| * @param selectedCategory
| */
| public void setSelectedCategory(Category selectedCategory) {
| // Prepare the member variable for outjection
| currentCategory = selectedCategory;
| // Refresh the itemList (wrap the Set in a List, no pre-defined or database sorting)
| itemList = new ArrayList<Item>(currentCategory.getItems());
| }
|
| @Remove @Destroy @End
| public void closeCatalog() {
| // Nothing to do here, Seam will close the managed persistence context when
| // this method returns.
| }
|
| }
|
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <ui:composition xmlns="http://www.w3.org/1999/xhtml"
| xmlns:ui="http://java.sun.com/jsf/facelets"
| xmlns:h="http://java.sun.com/jsf/html"
| xmlns:f="http://java.sun.com/jsf/core"
| xmlns:tr="http://myfaces.apache.org/trinidad"
| xmlns:s="http://jboss.com/products/seam/taglib"
| template="template.xhtml">
|
| <ui:define name="screen">Catalog</ui:define>
|
| <ui:define name="sidebar">
|
| <h1>#{messages['AuctionCategories']}:</h1>
|
| <tr:form>
| <!-- Let Trinidad inject the selected category into our conversation component -->
| <!-- Trinidad tree icons are really really ugly (HTML entities), there is no way to change them... -->
| <tr:tree var="cat" value="#{catalogCategoryAdapter.treeModel}">
| <f:facet name="nodeStamp">
| <tr:commandLink text="#{cat.name}" styleClass="nodeText">
| <tr:setActionListener from="#{cat}" to="#{catalog.selectedCategory}"/>
| </tr:commandLink>
| </f:facet>
| </tr:tree>
|
| </tr:form>
|
| </ui:define>
|
| <ui:define name="content">
|
| <!-- Headline -->
| <div class="section">
| <h1>
| <!-- Read the event context variable "currentCategory" that was outjected by our conversation component -->
| <h:outputText value="#{messages['PleaseSelectCategory']}" rendered="#{currentCategory == null}"/>
| <h:outputText value="#{messages['SelectedCategory']}: #{currentCategory.name}" rendered="#{currentCategory != null}"/>
| </h1>
| </div>
|
| <!-- Item table -->
| <div class="section">
| <!-- Read the conversation context variable "itemList", outjected by the catalog conversation component -->
| <h:outputText value="#{messages['NoItemsInCategory']}"
| rendered="#{itemList != null and itemList.rowCount==0}"/>
|
| <h:form>
| <h:dataTable value="#{itemList}" var="itm" rendered="#{itemList.rowCount>0}">
| <h:column>
| <f:facet name="header">#{messages['ItemName']}</f:facet>
| #{itm.name}
| </h:column>
| <h:column>
| <f:facet name="header">#{messages['ItemDescription']}</f:facet>
| #{itm.description}
| </h:column>
| <h:column>
| <f:facet name="header">#{messages['ItemSeller']}</f:facet>
| #{itm.seller.username}
| </h:column>
| <h:column>
| <f:facet name="header">#{messages['Action']}</f:facet>
| <s:link value="#{messages['PlaceBid']}" styleClass="button" action="#{placeBid.selectItem(itm)}"/>
| </h:column>
| </h:dataTable>
| </h:form>
|
| </div>
|
| </ui:define>
|
| </ui:composition>
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3978857#3978857
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3978857
More information about the jboss-user
mailing list