Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Active development of Seam Faces has been halted by Red Hat. This project has been migrated over to Apache DeltaSpike .

Seam Faces

Further unifies JSF and CDI, brings enhancements to the JSF programming model left out of the specification and integrates JSF with other Seam modules


Note: At the moment, Seam Faces requires CDI 1.0 as implemented by Weld 1.1.0 (GlassFish 3.1, JBoss 6, JBoss 7) and JBoss-Logging 3.0.0.Beta4 or higher.

To get started, add the following dependencies to your pom.xml:

<dependency>
   <groupId>org.jboss.seam.faces</groupId>
   <artifactId>seam-faces-api</artifactId>
   <version>3.1.0.Final</version>
</dependency>

<dependency>
   <groupId>org.jboss.seam.faces</groupId>
   <artifactId>seam-faces</artifactId>
   <version>3.1.0.Final</version>
   <scope>runtime</scope>
</dependency>

Module team

Name Module role Commit username (Git) Organization Hometown (Time zone)
Brian Leathem Lead bleathem TRIUMF Vancouver, Canada (UTC-8)
Dan Allen Contributor mojavelinux Red Hat, Inc. Laurel, MD, USA (UTC-5)
Lincoln Baxter, III Contributor lincolnthree Red Hat, Inc. Philadelphia, PA (UTC-5)
Stuart Douglas Contributor stuartwdouglas Red Hat, Inc. Sydney, AU (UTC+10)
Nicklas Karlsson Contributor nickarls Independent Turku, Finland (UTC+02)
Mark Struberg Contributor struberg Apache PMC Vienna, Austria (UTC+01)
José Rodolfo Freitas Contributor joserodolfofreitas Independent Brazil (UTC-03)
Want your name to appear in this list? Join us in #seam-dev on freenode and let us know you want to get involved.

Description

In many cases, the functionality provided by this module are prototypes for future versions of the JSF or CDI specifications.

Included in this package is the ability to interoperate with Seam's i18n support, debugging output for JSF, context implementations for JSF's flash scope (@FlashScoped) and view scope (@ViewScoped) (and look into Window scope, see ICEFaces Window Scope or PortletFaces scopes), @Inject into JSF system event listeners, converters and validators, support for nested conversations, view metadata components such as viewAction and restrictView, etc.

Any rendering UIComponent should be introduced into RichFaces rather than Seam, a change in policy from Seam 2. The Seam project doesn't want to be in the business of maintaining a component library since we already have a whole team for that work.

Further, this module contains Seam Managed Transactions.

Release plan

(status: draft) - This plan is still being defined.

Version Time frame Focus
3.1.0.Final January 16, 2012
3.1.0.CR1 December 1, 2011
3.1.0.Beta5 November 19, 2011
  • Object and Entity converters
3.1.0.Beta4 October 25, 2011
  • Activating beans based on the JSF project stage
3.1.0.Beta3 October 4, 2011
  • Fixed integration with Seam International
3.1.0.Beta2 August 26, 2011
  • Seam Security integration improvements
  • Removed the Faces Context initializer
3.1.0.Beta1 August 15, 2011
  • Removed combined maven module
  • Seam Catch integration improvements
3.0.2 June 20, 2011
  • MyFaces compatibility improvements
  • UIInputContianer fixes
3.0.1 April 17, 2011
3.0.0.Final April 1, 2011
  • Consolidated configuration of View Security
3.0.0.CR2 March 19, 2011
  • Use InputElement<T> instead of @InputField for injection of form input
  • Convenience classes for Validators/Converters
  • Bug fixes
3.0.0.CR1 February 23, 2011
  • Create a JSF bridge to Seam Catch
  • Bug fixes
3.0.0.Beta3 February 13, 2011
  • Declarative Exception Handling via Integration with Seam Catch
3.0.0.Beta2 December 23, 2010
  • Combined JAR (API + impl)
  • Automatic registration of FacesServlet
  • Migration to Seam Solder
3.0.0.Beta1 November 2, 2010
  • UIInputContainer tag for automatically adding label and message components to input fields
  • Support for CDI managed Converters/Validators (@Inject, @Scoped)
  • Seam Managed Transactions for JSF lifecycle integration in place (depends on persistence module)
3.0.0.Alpha3 May 19, 2010
  • i18n Seam Messages to FacesMessage adapter (w/Redirect support)
  • Cross-field form validation.
  • Load Facelets template files from classpath
3.0.0.Alpha2 April 15, 2010
  • View actions
  • javax.faces.bean.*Scoped aliases
  • @FlashScoped and @ViewScoped
  • Conversation boundary annotations and UI components
  • CDI / Faces Phase & System Event bridge
  • JSF API producers (FacesContext, ExternalContext, NavigationHandler, etc...)
  • Simplified EL name to conversation: #{conversation.transient}

Design whiteboard

This section serves as a whiteboard for design and ideas for this module. Once you've decided to pursue a feature, it should be added to JIRA as a feature request and optionally linked from this page.

A Killer Scope

Seam Faces needs to implement a Killer scope to enable developers to write applications with RESTful URLs in a straight forward manner. Other Scope implementations will be discussed and evaluated here, and the design of Seam's Killer scope will evolve.

Declarative exception handling and easy exception access for error pages via EL (status: whiteboard)

#{exceptionContext.cause} : Cause retrieved from the exception
#{exceptionContext.stackTrace} : Stack trace of the exception
#{exceptionContext.exception} : Exception handled by this page
#{exceptionContext.tree} : Print the component tree of the page that cause the error
#{exceptionContext.vars} : Enviroment variables from the request
  • Handle specific exception types
  • Handle HTTP errors
  • Adding exception handlers needs to be easier than what's already provided in JSF.
  • Exception Handler Priority controls?
  • Exception handlers should be CDI-managed beans, and need to provide hooks into navigation.
  • Ability to fire CDI Exception Events
  • Transaction controls?

Servlet: (Request, Response, CDI Lifecycle)
Faces: (ViewRoot, FacesContext, EL, NavigationHandler)

public interface ExceptionHandler<E extends Exception, S extends State>
{
  int getPriority();
  void handle(HandlerChain chain, S state, E e);
}

HandlerChain

public interface HandlerChain
{
  void next();
}

State (The base State is empty, but there will be different implementations for the various uses)

public interface State
{
}

FacesState

public interface FacesState extends State
{
  FacesContext getFacesContext();
  // Shortcut method for the users
  void navigate(String viewId);
}

Events

JSF 2.0 introduces the concept of system events, which through Seam Faces are now bridged to CDI events. But JSF overlooks several important events that would be useful:

  • PreNavigateEvent - raised immediately before navigation occurs, perhaps to allow the developer to add context variables or query parameters (see SEAMFACES-21)
  • BeforeRequestEvent - at the very start of the request
  • AfterRequestEvent - at the very end of the request (may not be that useful)

These can be renamed or turned into annotations as needed.

Conversation boundary control (status: in-progress)

Allow the use of @Begin and @End on a method to transition a conversation from transient to long-running and back. Also consider requiring a conversation to be running when a method is called with the @Conversational annotation, similar in nature to @TransactionAttribute(REQUIRED).

  • Allow timeout of conversation to be set using @Begin annotation
  • Set the default conversation timeout globally. This can be done using XML Bean configuration as soon as interface config is supported:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:s="urn:java:seam:core" 
   xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
   
   <s:Conversation>
      <s:specializes/>
      <s:timeout>5000</s:timeout>
   </s:Conversation>
   
</beans>

Advanced Conversation API (status: whiteboard)

org.jboss.seam.context.Conversation implements javax.enterprise.context.Conversation:

References can be obtained via Qualified @Injection:

@Inject org.jboss.seam.context.Conversation c;
@Inject @Seam org.jboss.seam.conversation.Conversation c;
@Inject @Seam javax.enterprise.context.Conversation c;

Injection points for JSF System Components/Objects (status: in progress)

Here are the issues that need to be completed in order to get this working without the need for Seam enhancements, both short term and long term:

Other than the above, We have a couple of options:

  1. Patch/hack/decorate into the JSF factories, replacing them with our implementations that provide injection, wherever necessary and possible in a portable way.
  2. Fix JSF (namely the WebContainerInjectionProvider - InjectionProvider interface) extension points to require implementations to provide such injection so that we don't need to hack and wrap.

In the mean time, while the spec issue goes through...

javax.faces.application.ApplicationWrapper can be used to provide injection for:

  • Validator
  • Converter
  • Component

Similar to a concept that Spring had going until they dropped it.

Fortunately, these are the most common use-cases; however...

Phase/SystemEvent Listeners

  • SystemEventListener
  • PhaseListener

It would be possible, to implement and register a Seam phase listener that would automatically delegate to any @Typed(PhaseListener.class) beans that are registered with CDI. This would be implemented as a chain (simply provide each listener the chance to take action via passthrough.)

The same could be done for event listeners. Simple add a global listener that would delegate to Seam-registered/injected listeners.

Action/ValueChange Listeners

These classes are not specifically injectable unless the developer provides them to JSF in an injectable way. Because live instances are required when binding to beans and supplying eventListeners to the system, this means you'd need to ask for an injected instance in your managedBean, or configurer, then pass that already injected instance into the component or system events system.

A simple user-solution would be to @Inject the listener directly into the ManagedBean from which it is referenced, or possibly specify the class as a @Named bean:

@Named
public MyListener implements ActionListener 
{   ...   }

@Named
public MyBean 
{
   @Inject @New MyListener listener;
   //...getters/setters
}

<h:commandButton listener="#{myBean.listener}" />

or

<h:commandButton listener="#{myListener}" /> -- this solution would mean that the same listener is re-used by all components.
  • ValueChangeListener
  • ActionListener

Seam Managed Transactions (status: whiteboard)

PhaseListener, Starts transaction for request before Restore View Phase, commits/rolls back transaction before Render Response, then opens a new Read Only transaction for Render Response and closes it after rendering is complete.

Conversation Scope and Nested Conversations (status: in progress)

Leverage CDI Conversation Contexts providing managed children and nesting:

Lincoln: I would like to investigate a method of attaching specific bean types to a specific qualified conversation, thus allowing / restricting access to specific beans depending on which qualified conversation is active. (E.g: In an instance of Conv. A, you have a potential instance of Bean A and Bean B. In an instance of Conv. B, you have a potential instance of Bean B and Bean C. Bean B may be instantiated to participate in either conversation, but instances of Beans A and C are exclusive to their respectively qualified conversations.)

Full Scoping Support via Annotations (status: alpha)

I think it's important that we put view/flash scoped beans high on the priority list for Seam Faces. The idea is to be able to annotate a class with the @javax.faces.bean.ViewScoped, @javax.faces.bean.FlashScoped annotation and have it use the JSF 2 view or flash scope as a backing store. They would be a regular CDI beans, not JSF managed beans. We are just reusing the scope annotations.

Note: We are supporting the javax.faces.bean.ViewScoped (and a new javax.faces.bean.FlashScoped) annotation so far, but do we already have support for @javax.faces.bean.xxx ? There are a lot of scoping annotations. Is this something that's already part of Weld, or do we need to support it for consistencies sake? I'd hate for people to use @ViewScoped, then try to use @javax.faces.bean.RequestScoped, and wonder why it's not working.

@javax.faces.bean.ViewScoped

Mark Struberg put together an impl of this, which he referenced at JSFDays. There is also another guy who put together a much simpler impl in a blog entry.

  1. http://github.com/struberg/myfaces-ext-cdi/tree/master/impl/src/main/java/org/apache/myfaces/extensions/cdi/impl/scopes/viewscoped/
  2. http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/

@javax.faces.bean.FlashScoped (new)

@FlashScoped is also something work implementing with annotation support. Right now, the only way to access Flash Scope is through a programmatic API. We need to get the @javax.faces.bean.FlashScoped annotation introduced into the JSF specification. @FlashScoped is the new, better solution for Transient Conversations spanning over page requests in Seam 2. FlashScoped should be used for FacesMessage propagation, etc...

We are now looking into providing our own flash scope implementation (tentatively called interaction scope) because we are not happy with the one in JSF 2.0).

Cross-field Validation (status: ALPHA)

Options discussion and analysis to come.

Enhanced Navigation, pages.xml, and PrettyFaces (status: whiteboard)

Tracking overlap between pages.xml and PrettyFaces.

Page cache (status: whiteboard)

Support Seam 2's s:cache tag.

Sensible defaults and global settings (status: whiteboard)

Allow setting the default values for includeViewParams=true and facesRedirect=true -- facesRedirect should probably be true by default.

Facelets on classpath (Status: ALPHA)

Load a Facelets template from a shared JAR as described in How do I load a Facelets view template from a shared JAR?

It appears this is unnecessary. JSF 2.0 will automatically resolve templates inside the META-INF directory of any classpath entry.

s:token

Implement the <s:token> tag from Seam 2 to guard against CSRF

REST component tags

Similar in spirit to the old JSP SQL tags, we could provide UI component tags that read from a REST API and spit the data back out onto the page, sort of like a pass-through. We would either allow XPath to consume the data or allow the JSON to be accessed with EL graph notation.

Other Ideas (status: whiteboard)

  • Headless JSF (JSF removed from servlet lifecycle, via mocks, etc.)
  • Stateless JSF (JSF which does not ever rely on session to preserve state.)

Definte component namespaces via Annotations (status: whiteboard)

The ability to somehow declare the Facelets tag attributes as well as the tag name and name space of any Java based custom component using annotations.

So something like:

@FacesComponent
@Facelets(name="Foo", name-space="com.bar.kaz/components")
public class Foo extends UIComponentBase {
}

With maybe some clever defaults, so you can omit the tag name and then the class name will be used instead.

Validation/Conversion

  • Implement ValidatorStateHelper and ConverterStateHelper to make state saving simpler in these behavior classes

Serving alternate content types in Facelets

Facelets supports setting the Content-type of the response using the contentType attribute of f:view. However, this isn't always enough to get the browser to recognize that it's receiving non-HTML content. It may be necessary to support the Content-disposition as well as described in the forum post How to set Content-Type header? This should be easier to accomplish w/ Seam Faces.

Smart injection support in components (status: whiteboard)

Additionally, some smart injection might be used to inject the dynamic values from the value expressions in the attribute map of the component, which at the same time could be read by the editors to help in content assisting:

@FacesComponent
@Facelets(name-space="com.bar.kaz/components")
public class Foo extends UIComponentBase {

@Inject
@Attribute
String color; // will be injected with getAttributes("color") 

@Inject
@Attribute(shortDescription="This will determine the ...", required=true)
String style;

}