Seam

From Wiki RB4

Introduction

Seam manages components, that means it manages the complete lifecycle and scope of the components (inversion of control principle), named as context of a component. Thereto it injects dependencies to the components (dependency injection).

Most Seam application use session beans as JSF action listeners.

Seam lets you use a JSF EL expression inside EJB-QL. Under the covers, this results in an ordinary JPA setParameter() call on the standard JPA Query object.

Seam integrates Hibernate Validator and lets you use it for data validation (even if you are not using Hibernate for persistence).

Installation and Configuration

  • download jboss-seam-2.0.2.SP1.zip and extract to <ECLIPSE_WORKSPACE>
  • add jboss.home to <SEAM_DIR>\build.properties

Components configuration

  • <WAR-File>/WEB-INF/components.xml
<components xmlns="http://jboss.com/products/seam/components"
           xmlns:core="http://jboss.com/products/seam/core"
           xmlns:security="http://jboss.com/products/seam/security"
           xmlns:transaction="http://jboss.com/products/seam/transaction"
           ...>
  ...
  <security:identity authenticate-method="#{authenticator.authenticate}"/>
  <!--
    The standard action #{identity.login} in an facelet calls actually the method authenticate() of the seam 
    component authenticator.
  -->
</components>


Libs

Annotations

Seam defines own annotations and uses some other annotations.

org.hibernate.validator.Length

@org.hibernate.validator.Length(min=<Number>, max=<Number>)
<attribute declaration>

for length validation.

org.hibernate.validator.NotNull

@org.hibernate.validator.NotNull
<attribute declaration>

for validation.

org.jboss.seam.annotations.datamodel.DataModel

@org.jboss.seam.annotations.datamodel.DataModel[(scope=ScopeType.<TYPE>)]
<attribute declaration>

The @DataModel annotation exposes an attibute of type java.util.List to the JSF page as an instance of javax.faces.model.DataModel. This allows us to use the list in a JSF <h:dataTable> with clickable links for each row. In this case, the DataModel is made available in a session context variable named messageList.

org.jboss.seam.annotations.datamodel.DataModelSelection

@org.jboss.seam.annotations.datamodel.DataModelSelection
<attribute declaration>

The @DataModelSelection annotation tells Seam to inject the List element that corresponded to the clicked link.

org.jboss.seam.annotations.Factory

@org.jboss.seam.annotations.Factory("<context variable name>")
<method_declaration>

The @Factory annotation tells Seam to create an instance of the bean and invoke the method to initialize the value. We call method a factory method. Marks a method as a factory method for a context variable. A factory method is called whenever no value is bound to the named context variable, and is expected to initialize the value of the context variable. There are two kinds of factory methods. Factory methods with void return type are responsible for outjecting a value to the context variable. Factory methods which return a value do not need to explicitly ouject the value, since Seam will bind the returned value to the specified scope. This annotation supports use of the Seam "factory component" pattern.

org.jboss.seam.annotations.In

@org.jboss.seam.annotations.In
<attribute_declaration>

The attribute is injected by Seam. Examples for injections are EntityManager or FacesMessages.

org.jboss.seam.annotations.Logger

@org.jboss.seam.annotations.Logger
private org.jboss.seam.log.Log log;

org.jboss.seam.annotations.Name

@org.jboss.seam.annotations.Name("<Name>")
<class_declaration>

specifies the name of the Seam component. This name must be unique within the Seam application. When JSF asks Seam to resolve a context variable with a name that is the same as a Seam component name, and the context variable is currently undefined (null), Seam will instantiate that component, and bind the new instance to the context variable.


org.jboss.seam.annotations.Out

@org.jboss.seam.annotations.Out[([required=(true|false) [,scope=<SCOPE>])]
<attribute_declaration>

The @Out annotation then exposes the selected value directly to the page. So ever time a row of the clickable list is selected, the row object is injected to the attribute of the stateful bean, and the subsequently outjected to the event context variable named as the attribute name.

org.jboss.seam.annotations.Scope

@org.jboss.seam.annotations.Scope(org.jboss.seam.ScopeType.<SCOPE_TYPE>)
<class_declaration>

specifies the scope of a seam component. Each Seam component type has a default scope. Types are:

Standard components

Identity

  • Name "identity"
@org.jboss.seam.annotations.In
private org.jboss.seam.security.Identity idendity;

is a standard component of the Seam security model und lives as long as the session.

Mehtods:

  • getUsername()
  • getPassword()

Standard Functionality

JBoss EL

Seam provides an extension to the standard Unified Expression Language (EL) called JBoss EL.

Logging

The org.jboss.seam.log.log (s. annotations) class has a specialised syntax e.g.

log.info("creating component '#0' on #1", name(), date());
log.info("#{<SEAM COMPONENT>.<attribute>}");

Methods:

  • info()
  • debug()
  • error()

Security

The security functionality was extended during between version 2.0.2 to 2.1.0 (s. documentation).

Authentication

For less complex applications Seam offers a simple method:

  • configure components.xml to call the simple authentication method
  • write an authentication method (no parameter, return true if success, else false) (s. Seam class identity)
  • write a login form

Pageflow

There are two ways to define pageflow in Seam:

  • Using JSF or Seam navigation rules - the stateless navigation model
  • Using jPDL - the stateful navigation model

You can use them together or independently or not at all.

Stateless Navigation Model

The stateless model defines a mapping from a set of named, logical outcomes of an event directly to the resulting page of the view. The navigation rules are entirely oblivious to any state held by the application other than what page was the source of the event. This means that your action listener methods must sometimes make decisions about the page flow, since only they have access to the current state of the application.

You can specify JSF- or Seam navigation rule.

  • seam pageflow navigation rules in <WAR-File>/WEB-INF/pages.xml
<pages>
  <page view-id="<NAME>" [action="#{<COMPONENT>.<METHOD>}"]>
    [<action if="<CONDITION>" execute="#{<COMPONENT>.<METHOD>}"/>]
  </page>
</pages>

or

  • as JSF navigation rule in faces-config.xml.
<navigation-rule>
  <from-view-id>/numberGuess.jsp</from-view-id>
    <navigation-case>
      <from-outcome>guess</from-outcome>
      <to-view-id>/numberGuess.jsp</to-view-id>
      <redirect/>
    </navigation-case>
    <navigation-case>
      <from-outcome>win</from-outcome>
      <to-view-id>/win.jsp</to-view-id>
      <redirect/>
   </navigation-case>
</navigation-rule>
  • If you find navigation rules overly verbose, you can return view ids directly from your action listener methods, e.g.:
public String guess() 
{
  if (guess==randomNumber) return "/win.jsp";
  if (++guessCount==maxGuesses) return "/searchResults.jsp?searchPattern=#{searchAction.searchPattern}";
  return null;
}

Stateful Navigation Model

The stateful model defines a set of transitions between a set of named, logical application states. In this model, it is possible to express the flow of any user interaction entirely in the jPDL pageflow definition, and write action listener methods that are completely unaware of the flow of the interaction.


API

FacesMessages

FacesMessages.instance().add("...");

Seam tags

Seam use Facelets for the user interface. An example of an xhtml file is

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:s="http://jboss.com/products/seam/taglib"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

validateAll

This JSF component tells JSF to validate all contained input fields against the Hibernate Validator annotations specified in the entitiy bean.

Applications

Reources

  • Seam in Action by Dan Allen in C:\Uwes\Documents\Software_Development\Programming\Frameworks\Seam\SeaminAction.pdf, Source code extracted to <ECLIPSE_WORKSPACE>/seaminaction