[jboss-cvs] jboss-seam/doc/reference/en/modules ...

Gavin King gavin.king at jboss.com
Mon Oct 16 07:23:14 EDT 2006


  User: gavin   
  Date: 06/10/16 07:23:14

  Modified:    doc/reference/en/modules         annotations.xml
                        components.xml concepts.xml controls.xml drools.xml
                        i18n.xml jms.xml
  Added:       doc/reference/en/modules         events.xml
  Log:
  update to Seam 1.1, some reorg
  
  Revision  Changes    Path
  1.43      +83 -7     jboss-seam/doc/reference/en/modules/annotations.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: annotations.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/annotations.xml,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -b -r1.42 -r1.43
  --- annotations.xml	18 Sep 2006 01:09:07 -0000	1.42
  +++ annotations.xml	16 Oct 2006 11:23:14 -0000	1.43
  @@ -164,6 +164,19 @@
                       </itemizedlist>
                   </listitem>
               </varlistentry>   
  +            <varlistentry  id="synchronized-annotation">
  +                <term><literal>@Synchronized</literal></term>
  +                <listitem>
  +                    <programlisting><![CDATA[@Synchronized(timeout=1000)]]></programlisting>
  +                    <para>
  +                        Specifies that a component is accessed concurrently
  +                        by multiple clients, and that Seam should serialize
  +                        requests. If a request is not able to obtain its
  +                        lock on the component in the given timeout period,
  +                        an exception will be raised.
  +                    </para>
  +                </listitem>
  +            </varlistentry>   
           </variablelist>
       </section>
   
  @@ -1009,20 +1022,31 @@
       	</para>
       	
       	<variablelist spacing="compact">
  -            <varlistentry  id="around-annotation">
  -                <term><literal>@Around</literal></term>
  +            <varlistentry  id="interceptor-annotation">
  +                <term><literal>@Interceptor</literal></term>
                   <listitem>
  -                    <programlisting><![CDATA[@Around({SomeInterceptor.class, OtherInterceptor.class})]]></programlisting>
  +                    <programlisting><![CDATA[@Interceptor(stateless=true)]]></programlisting>
  +                    <para>
  +                        Specifies that this interceptor is stateless and Seam may optimize
  +                        replication.
  +                    </para>
  +                </listitem>
  +                <listitem>
  +                    <programlisting><![CDATA[@Interceptor(type=CLIENT)]]></programlisting>
  +                    <para>
  +                        Specifies that this interceptor is a "client-side" interceptor that
  +                        is called before the EJB container.
  +                    </para>
  +                </listitem>
  +                <listitem>
  +                    <programlisting><![CDATA[@Interceptor(around={SomeInterceptor.class, OtherInterceptor.class})]]></programlisting>
                       <para>
                           Specifies that this interceptor is positioned higher in the stack than
                           the given interceptors.
                       </para>
                   </listitem>
  -            </varlistentry>
  -            <varlistentry  id="within-annotation">
  -                <term><literal>@Within</literal></term>
                   <listitem>
  -                    <programlisting><![CDATA[@Within({SomeInterceptor.class, OtherInterceptor.class})]]></programlisting>
  +                    <programlisting><![CDATA[@Interceptor(within={SomeInterceptor.class, OtherInterceptor.class})]]></programlisting>
                       <para>
                           Specifies that this interceptor is positioned deeper in the stack than
                           the given interceptors.
  @@ -1034,6 +1058,58 @@
       </section> 
   
       <section>
  +      <title>Annotations for asynchronicity</title>
  +      <para>
  +          The following annotations are used to declare an asynchronous method:
  +      </para>
  +
  +      <variablelist spacing="compact">
  +            <varlistentry id="asynchronous-annotation">
  +                <term><literal>@Asynchronous</literal></term>
  +                <listitem>
  +                    <programlisting><![CDATA[@Asynchronous]]></programlisting>
  +                    <para>
  +                        Specifies that the method call is processed asynchronously.
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry id="duration-annotation">
  +                <term><literal>@Duration</literal></term>
  +                <listitem>
  +                    <programlisting><![CDATA[@Duration]]></programlisting>
  +                    <para>
  +                        Specifies that a parameter of the asynchronous call is
  +                        the duration before the call is processed (or first
  +                        processed for recurring calls).
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry id="expiration-annotation">
  +                <term><literal>@Expiration</literal></term>
  +                <listitem>
  +                    <programlisting><![CDATA[@Expiration]]></programlisting>
  +                    <para>
  +                        Specifies that a parameter of the asynchronous call is
  +                        the datetime at which the call is processed (or first
  +                        processed for recurring calls).
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry id="intervalduration-annotation">
  +                <term><literal>@IntervalDuration</literal></term>
  +                <listitem>
  +                    <programlisting><![CDATA[@IntervalDuration]]></programlisting>
  +                    <para>
  +                        Specifies that an asynchronous method call recurs, and
  +                        that the annotationed parameter is duration between
  +                        recurrences.
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +        </variablelist>
  +    </section>
  +    
  +    <section>
       	<title>Annotations for use with JSF <literal>dataTable</literal></title>
       	<para>
       	    The following annotations make it easy to implement clickable lists
  
  
  
  1.41      +227 -68   jboss-seam/doc/reference/en/modules/components.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: components.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/components.xml,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -b -r1.40 -r1.41
  --- components.xml	14 Oct 2006 22:49:34 -0000	1.40
  +++ components.xml	16 Oct 2006 11:23:14 -0000	1.41
  @@ -73,14 +73,6 @@
                   </listitem>
               </varlistentry>
               <varlistentry>
  -                <term><literal>statelessContext</literal></term>
  -                <listitem>
  -                    <para>
  -                        Manager component for the stateless context object
  -                    </para>
  -                </listitem>
  -            </varlistentry>
  -            <varlistentry>
                   <term><literal>facesContext</literal></term>
                   <listitem>
                       <para>
  @@ -222,6 +214,22 @@
                               an event of a particular type and distribute to all
                               observers.
                           </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>raiseAsynchronousEvent(String type)</literal> &mdash; 
  +                            raise an event to be processed asynchronously by the EJB3
  +                            timer service.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>raiseTimedEvent(String type, ....)</literal> &mdash; 
  +                            schedule an event to be processed asynchronously by the EJB3
  +                            timer service.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
                           <para>
                               <literal>addListener(String type, String methodBinding)</literal> 
                               &mdash; add an observer for a particular event type.
  @@ -249,38 +257,43 @@
                   </listitem>
                </varlistentry>
               <varlistentry>
  -                <term><literal>pojoCache</literal></term>
  +                <term><literal>expressions</literal></term>
                   <listitem>
                       <para>
  -                        Manager component for a JBoss Cache <literal>PojoCache</literal> 
  -                        instance.
  +                        An API for creating value and method bindings.
                       </para>
                       <itemizedlist>
                           <listitem>
                           <para>
  -                            <literal>pojoCache.cfgResourceName</literal> &mdash; the name of 
  -                            the configuration file. Default to <literal>treecache.xml</literal>.
  +                            <literal>createValueBinding(String expression)</literal> &mdash; create
  +                            a value binding object.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>createMethodBinding(String expression)</literal> &mdash; create
  +                            a method binding object.
                           </para>
                           </listitem>
                       </itemizedlist>
                   </listitem>
               </varlistentry>
               <varlistentry>
  -                <term><literal>renderParameters</literal></term>
  +                <term><literal>pojoCache</literal></term>
                   <listitem>
                       <para>
  -                        Allows JSF form controls to be bound to a "render parameter"
  -                        which will be accessible via <literal>@RequestParameter</literal>
  -                        during the subsequent render phase even if a browser redirect
  -                        occurs. 
  +                        Manager component for a JBoss Cache <literal>PojoCache</literal> 
  +                        instance.
                       </para>
  +                    <itemizedlist>
  +                        <listitem>
                       <para>
  -                        For example, the value entered in this input field: 
  -                        <literal>&lt;inputText value="#{renderParameters.searchString}"/&gt;</literal>
  -                        will be available via <literal>@RequestParameter("searchString")</literal>
  -                        when the form is submitted.
  +                            <literal>pojoCache.cfgResourceName</literal> &mdash; the name of 
  +                            the configuration file. Default to <literal>treecache.xml</literal>.
                       </para>
                   </listitem>
  +                    </itemizedlist>
  +                </listitem>
               </varlistentry>
               <varlistentry>
                   <term><literal>uiComponent</literal></term>
  @@ -316,10 +329,20 @@
                   </listitem>
               </varlistentry>
               <varlistentry>
  +                <term><literal>timezone</literal></term>
  +                <listitem>
  +                    <para>
  +                        The Seam timezone. The timezone is session scoped.
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry>
                   <term><literal>resourceBundle</literal></term>
                   <listitem>
                       <para>
  -                        The Seam resource bundle. The resource bundle is session scoped.
  +                        The Seam resource bundle. The resource bundle is session scoped. The Seam
  +                        resource bundle performs a depth-first search for keys in a list of Java
  +                        resource bundles.
                       </para>
                       <itemizedlist>
                           <listitem>
  @@ -391,6 +414,40 @@
                   </listitem>
               </varlistentry>
               <varlistentry>
  +                <term><literal>timezoneSelector</literal></term>
  +                <listitem>
  +                    <para>
  +                        Supports selection of the timezone either at configuration time, 
  +                        or by the user at runtime.
  +                    </para>
  +                    <itemizedlist>
  +                        <listitem>
  +                        <para>
  +                            <literal>select()</literal> &mdash; select the specified locale.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>timezoneSelector.timezone</literal> &mdash; the actual
  +                            <literal>java.util.TimeZone</literal>.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>timezoneSelector.timeZoneId</literal> &mdash; the 
  +                            stringified representation of the timezone.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>timezoneSelector.cookieEnabled</literal> &mdash; specifies
  +                            that the timezone selection should be persisted via a cookie.
  +                        </para>
  +                        </listitem>
  +                    </itemizedlist>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry>
                   <term><literal>messages</literal></term>
                   <listitem>
                       <para>
  @@ -478,6 +535,23 @@
                           </listitem>
                           <listitem>
                           <para>
  +                            <literal>isNested()</literal> &mdash; is the current conversation a
  +                            nested conversation?
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>isLongRunning()</literal> &mdash; is the current conversation a
  +                            long-running conversation?
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>getId()</literal> &mdash; returns the current conversation id
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
                               <literal>getParentId()</literal> &mdash; returns the conversation id
                               of the parent conversation
                           </para>
  @@ -528,6 +602,13 @@
                           </listitem>
                           <listitem>
                           <para>
  +                            <literal>beginPageflow(String pageflowName)</literal> &mdash; begin a 
  +                            long-running conversation with a pageflow (equivalent to 
  +                            <literal>@Begin(pageflow="...")</literal>).
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
                               <literal>end()</literal> &mdash; end a long-running conversation
                               (equivalent to <literal>@End</literal>).
                           </para>
  @@ -544,6 +625,12 @@
                               the conversation stack.
                           </para>
                           </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>changeFlushMode(FlushModeType flushMode)</literal> &mdash; change 
  +                            the flush mode of the conversation.
  +                        </para>
  +                        </listitem>
                       </itemizedlist>
                   </listitem>
               </varlistentry>
  @@ -684,6 +771,18 @@
                           </listitem>
                           <listitem>
                           <para>
  +                            <literal>businessProcess.hasCurrentTask()</literal> &mdash; is a task
  +                            instance associated with the current conversation?
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>businessProcess.hasCurrentProcess()</literal> &mdash; is a process
  +                            instance associated with the current conversation.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
                               <literal>createProcess(String name)</literal> &mdash; create an
                               instance of the named process definition and associate it with
                               the current conversation.
  @@ -701,6 +800,24 @@
                               associated with the current conversation.
                           </para>
                           </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>initTask(Long id)</literal> &mdash; associate the task with
  +                            the given id with the current conversation.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>initProcess(Long id)</literal> &mdash; associate the process 
  +                            with the given id with the current conversation.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
  +                            <literal>transition(String transitionName)</literal> &mdash; trigger
  +                            the transition.
  +                        </para>
  +                        </listitem>
                       </itemizedlist>
                   </listitem>
               </varlistentry>
  @@ -842,26 +959,14 @@
                       <itemizedlist>
                           <listitem>
                           <para>
  -                            <literal>org.jboss.seam.core.init.componentClasses</literal> &mdash; a list of class 
  -                            names of Seam components to be installed. (The class name, not the component name!)
  -                        </para>
  -                        </listitem>
  -                        <listitem>
  -                        <para>
  -                            <literal>org.jboss.seam.core.init.managedPersistenceContexts</literal> &mdash; a 
  -                            list of component names of Seam managed persistence contexts to be installed.
  +                            <literal>org.jboss.seam.core.init.jndiPattern</literal> &mdash; the JNDI
  +                            pattern used for looking up session beans
                           </para>
                           </listitem>
                           <listitem>
                           <para>
  -                            <literal>org.jboss.seam.core.init.managedSessions</literal> &mdash; a list of 
  -                            component names of Seam managed Hibernate sessions to be installed.
  -                        </para>
  -                        </listitem>
  -                        <listitem>
  -                        <para>
  -                            <literal>org.jboss.seam.core.init.jbpmSessionFactoryName</literal> &mdash; the
  -                            name of the jBPM session factory
  +                            <literal>org.jboss.seam.core.init.debug</literal> &mdash; enable Seam
  +                            debug mode
                           </para>
                           </listitem>
                           <listitem>
  @@ -890,6 +995,13 @@
                           </listitem>
                           <listitem>
                           <para>
  +                            <literal>org.jboss.seam.core.manager.concurrentRequestTimeout</literal> &mdash; 
  +                            maximum wait time for a thread attempting to gain a lock on the long-running 
  +                            conversation context.
  +                        </para>
  +                        </listitem>
  +                        <listitem>
  +                        <para>
                               <literal>org.jboss.seam.core.manager.conversationIdParameter</literal> &mdash; 
                               the request parameter used to propagate the conversation id, default
                               to <literal>conversationId</literal>.
  @@ -951,28 +1063,6 @@
                   </listitem>
               </varlistentry>
               <varlistentry>
  -                <term><literal>org.jboss.seam.core.hibernate</literal></term>
  -                <listitem>
  -                    <para>
  -                        Bootstraps a Hibernate <literal>SessionFactory</literal>. Install 
  -                        as class <literal>org.jboss.seam.core.HibernateSessionFactory</literal>. 
  -                        This is most useful when using Seam with Hibernate inside a Java EE
  -                        application server.
  -                    </para>
  -                    <itemizedlist>
  -                        <listitem>
  -                        <para>
  -                            <literal>org.jboss.seam.core.hibernate.cfgResourceName</literal> &mdash; 
  -                            the path to the configuration file. Default to <literal>hibernate.cfg.xml</literal>.
  -                        </para>
  -                        </listitem>
  -                    </itemizedlist>
  -                    <para>
  -                        See the API JavaDoc for further configuration properties.
  -                    </para>
  -                </listitem>
  -            </varlistentry>
  -            <varlistentry>
                   <term><literal>org.jboss.seam.core.jbpm</literal></term>
                   <listitem>
                       <para>
  @@ -998,6 +1088,24 @@
                   </listitem>
               </varlistentry>
               <varlistentry>
  +                <term><literal>org.jboss.seam.core.conversationEntries</literal></term>
  +                <listitem>
  +                    <para>
  +                        Internal session-scoped component recording the active long-running conversations
  +                        between requests.
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry>
  +                <term><literal>org.jboss.seam.core.persistenceContexts</literal></term>
  +                <listitem>
  +                    <para>
  +                        Internal component recording the persistence contexts which were used in
  +                        the current conversation.
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry>
                   <term><literal>org.jboss.seam.jms.queueConnection</literal></term>
                   <listitem>
                       <para>
  @@ -1077,7 +1185,7 @@
           
       	<variablelist spacing="compact">
               <varlistentry>
  -                <term><literal><emphasis>&lt;managedPersistenceContext&gt;</emphasis></literal></term>
  +                <term><literal><emphasis>&lt;entityManager&gt;</emphasis></literal></term>
                   <term><literal>org.jboss.seam.core.ManagedPersistenceContext</literal></term>
                   <listitem>
                       <para>
  @@ -1087,7 +1195,12 @@
                       <itemizedlist>
                           <listitem>
                           <para>
  -                            <literal><emphasis>&lt;managedPersistenceContext&gt;</emphasis>.persistenceUnitJndiName</literal> 
  +                            <literal><emphasis>&lt;entityManager&gt;</emphasis>.entityManagerFactory</literal> 
  +                            &mdash; a value binding expression that evaluates to an instance of 
  +                            <literal>EntityManagerFactory</literal>.
  +                        </para>
  +                        <para>
  +                            <literal><emphasis>&lt;entityManager&gt;</emphasis>.persistenceUnitJndiName</literal> 
                               &mdash; the JNDI name of the entity manager factory, default to 
                               <literal>java:/<emphasis>&lt;managedPersistenceContext&gt;</emphasis></literal>.
                           </para>
  @@ -1096,7 +1209,28 @@
                   </listitem>
               </varlistentry>
               <varlistentry>
  -                <term><literal><emphasis>&lt;managedSession&gt;</emphasis></literal></term>
  +                <term><literal><emphasis>&lt;entityManagerFactory&gt;</emphasis></literal></term>
  +                <term><literal>org.jboss.seam.core.EntityManagerFactory</literal></term>
  +                <listitem>
  +                    <para>
  +                        Manages a JPA <literal>EntityManagerFactory</literal>. This is most useful
  +                        when using JPA outside of an EJB 3.0 supporting environment.
  +                    </para>
  +                    <itemizedlist>
  +                        <listitem>
  +                        <para>
  +                            <literal>entityManagerFactory.persistenceUnitName</literal> &mdash; 
  +                            the name of the persistence unit.
  +                        </para>
  +                        </listitem>
  +                    </itemizedlist>
  +                    <para>
  +                        See the API JavaDoc for further configuration properties.
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry>
  +                <term><literal><emphasis>&lt;session&gt;</emphasis></literal></term>
                   <term><literal>org.jboss.seam.core.ManagedSession</literal></term>
                   <listitem>
                       <para>
  @@ -1105,7 +1239,12 @@
                       <itemizedlist>
                           <listitem>
                           <para>
  -                            <literal><emphasis>&lt;managedSession&gt;</emphasis>.sessionFactoryJndiName</literal> 
  +                            <literal><emphasis>&lt;session&gt;</emphasis>.sessionFactory</literal> 
  +                            &mdash; a value binding expression that evaluates to an instance of 
  +                            <literal>SessionFactory</literal>.
  +                        </para>
  +                        <para>
  +                            <literal><emphasis>&lt;session&gt;</emphasis>.sessionFactoryJndiName</literal> 
                               &mdash; the JNDI name of the session factory, default to 
                               <literal>java:/<emphasis>&lt;managedSession&gt;</emphasis></literal>.
                           </para>
  @@ -1114,6 +1253,26 @@
                   </listitem>
               </varlistentry>
               <varlistentry>
  +                <term><literal><emphasis>&lt;sessionFactory&gt;</emphasis></literal></term>
  +                <term><literal>org.jboss.seam.core.HibernateSessionFactory</literal></term>
  +                <listitem>
  +                    <para>
  +                        Manages a Hibernate <literal>SessionFactory</literal>.  
  +                    </para>
  +                    <itemizedlist>
  +                        <listitem>
  +                        <para>
  +                            <literal>org.jboss.seam.core.hibernate.cfgResourceName</literal> &mdash; 
  +                            the path to the configuration file. Default to <literal>hibernate.cfg.xml</literal>.
  +                        </para>
  +                        </listitem>
  +                    </itemizedlist>
  +                    <para>
  +                        See the API JavaDoc for further configuration properties.
  +                    </para>
  +                </listitem>
  +            </varlistentry>
  +            <varlistentry>
                   <term><literal><emphasis>&lt;managedQueueSender&gt;</emphasis></literal></term>
                   <term><literal>org.jboss.seam.jms.ManagedQueueSender</literal></term>
                   <listitem>
  
  
  
  1.35      +91 -550   jboss-seam/doc/reference/en/modules/concepts.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: concepts.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/concepts.xml,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -b -r1.34 -r1.35
  --- concepts.xml	16 Oct 2006 00:10:45 -0000	1.34
  +++ concepts.xml	16 Oct 2006 11:23:14 -0000	1.35
  @@ -609,87 +609,6 @@
           </sect2>
           
           <sect2>
  -            <title>The <literal>Mutable</literal> interface</title>
  -            <para>
  -                Many application servers feature an amazingly broken implementation of 
  -                <literal>HttpSession</literal> clustering, where changes to the state of mutable
  -                objects bound to the session are only replicated when the application calls
  -                <literal>setAttribute()</literal> explicitly. This is a source of bugs that can
  -                not effectively be tested for at development time, since they will only manifest
  -                when failover occurs. Furthermore, the actual replication message contains the
  -                entire serialized object graph bound to the session attribute, which inefficient.
  -            </para>
  -            <para>
  -                Of course, EJB stateful session beans must perform automatic dirty checking and 
  -                replication of mutable state and a sophisticated EJB container can introduce
  -                optimizations such as attribute-level replication. Unfortunately, not all Seam
  -                users have the good fortune to be working in an environment that supports EJB 3.0.
  -                So, for session and conversation scoped JavaBean and entity bean components, 
  -                Seam provides an extra layer of cluster-safe state management over the top
  -                of the web container session clustering.
  -            </para>
  -            <para>
  -                For session or conversation scoped JavaBean components, Seam automatically forces 
  -                replication to occur by calling <literal>setAttribute()</literal> once in every 
  -                request that the component was invoked by the application. Of course, this strategy 
  -                is inefficient for read-mostly components. You can control this behavior by 
  -                implementing the <literal>org.jboss.seam.core.Mutable</literal> interface, or by
  -                extending <literal>org.jboss.seam.core.AbstractMutable</literal>, and writing
  -                your own dirty-checking logic inside the component. For example,
  -            </para>
  -            
  -            <programlisting><![CDATA[@Name("account")
  -public class Account extends AbstractMutable
  -{
  -    private BigDecimal balance;
  -    
  -    public void setBalance(BigDecimal balance)
  -    {
  -        setDirty(this.balance, balance);
  -        this.balance = balance;
  -    }
  -    
  -    public BigDecimal getBalance()
  -    {
  -        return balance;
  -    }
  -    
  -    ...
  -    
  -}]]></programlisting>
  -            
  -            <para>
  -                For session or conversation scoped entity bean components, Seam automatically forces 
  -                replication to occur by calling <literal>setAttribute()</literal> once in every 
  -                request. This strategy is not efficient, so session or conversation scope entity
  -                beans should be used with care. You can always write a stateful session bean
  -                or JavaBean component to "manage" the entity bean instance. For example,
  -            </para>
  -
  -            <programlisting><![CDATA[@Stateful
  - at Name("account")
  -public class AccountManager extends AbstractMutable
  -{
  -    private Account account; // an entity bean
  -    
  -    @Unwrap
  -    public void getAccount()
  -    {
  -        return account;
  -    }
  -    
  -    ...
  -    
  -}]]></programlisting>
  -
  -            <para>
  -                Note that the <literal>EntityHome</literal> class in the Seam Framework provides
  -                a great example of this pattern.
  -            </para>
  -
  -        </sect2>
  -        
  -        <sect2>
               <title>Built-in components</title>
               <para>
                   Like many good frameworks, Seam eats its own dogfood and is implemented mostly as
  @@ -1122,6 +1041,37 @@
       </sect1>
       
       <sect1>
  +        <title>Lifecycle methods</title>
  +        <para>
  +            Session bean and entity bean Seam components support all the usual EJB 3.0 lifecycle
  +            callback (<literal>@PostConstruct</literal>, <literal>@PreDestroy</literal>, etc).
  +            Seam extends all of these callbacks except <literal>@PreDestroy</literal> to JavaBean
  +            components. But Seam also defines its own component lifecycle callbacks.
  +        </para>
  +        <para>
  +            The <literal>@Create</literal> method is called every time Seam instantiates a
  +            component. Unlike the <literal>@PostConstruct</literal> method, this method is
  +            called after the component is fully constructed by the EJB container, and has
  +            access to all the usual Seam functionality (bijection, etc). Components may
  +            define only one <literal>@Create</literal> method.
  +        </para>
  +        <para>
  +            The <literal>@Destroy</literal> method is called when the context that the Seam
  +            component is bound to ends. Components may define only one <literal>@Destroy</literal> 
  +            method. Stateful session bean components <emphasis>must</emphasis> define a method
  +            annotated <literal>@Destroy @Remove</literal>.
  +        </para>
  +        <para>
  +            Finally, a related annotation is the <literal>@Startup</literal> annotation, which
  +            may be applied to any application or session scoped component. The 
  +            <literal>@Startup</literal> annotation tells Seam to instantiate the component
  +            immediately, when the context begins, instead of waiting until it is first 
  +            referenced by a client. It is possible to control the order of instantiation
  +            of startup components by specifying <literal>@Startup(depends={....})</literal>.
  +        </para>
  +    </sect1>
  +    
  +    <sect1>
           <title>Logging</title>
           <para>
               Who is not totally fed up with seeing noisy code like this?
  @@ -1179,461 +1129,83 @@
       </sect1>
       
       <sect1>
  -    	<title>Seam interceptors</title>
  -    	<para>
  -    		EJB 3.0 introduced a standard interceptor model for session bean components. To add an
  -    		interceptor to a bean, you need to write a class with a method annotated 
  -    		<literal>@AroundInvoke</literal> and annotate the bean with an
  -    		<literal>@Interceptors</literal> annotation that specifies the name of the interceptor
  -    		class. For example, the following interceptor checks that the user is logged in before
  -    		allowing invoking an action listener method:
  -    	</para>
  -    	
  -    	<programlisting><![CDATA[public class LoggedInInterceptor {
  -
  -   @AroundInvoke
  -   public Object checkLoggedIn(InvocationContext invocation) throws Exception {
  -   
  -      boolean isLoggedIn = Contexts.getSessionContext().get("loggedIn")!=null;
  -      if (isLoggedIn) {
  -         //the user is already logged in
  -         return invocation.proceed();
  -      }
  -      else {
  -         //the user is not logged in, fwd to login page
  -         return "login";
  -      }
  -   }
  -
  -}]]></programlisting>
  -
  -		<para>
  -		    To apply this interceptor to a session bean which acts as an action listener, we must
  -		    annotate the session bean <literal>@Interceptors(LoggedInInterceptor.class)</literal>.
  -		    This is a somewhat ugly annotation. Seam builds upon the interceptor framework in
  -		    EJB3 by allowing you to use <literal>@Interceptors</literal> as a meta-annotation. In
  -		    our example, we would create an <literal>@LoggedIn</literal> annotation, as follows:
  -		</para>
  -    	
  -    	<programlisting><![CDATA[@Target(TYPE)
  - at Retention(RUNTIME)
  - at Interceptors(LoggedInInterceptor.class)
  -public @interface LoggedIn {}]]></programlisting>
  -
  -        <para>
  -            We can now simply annotate our action listener bean with <literal>@LoggedIn</literal>
  -            to apply the interceptor.
  -        </para>
  -        
  -        <programlisting><![CDATA[@Stateless
  - at Name("changePasswordAction")
  - at LoggedIn
  - at Interceptors(SeamInterceptor.class)
  -public class ChangePasswordAction implements ChangePassword { 
  -    
  -    ...
  -    
  -    public String changePassword() { ... }
  -    
  -}]]></programlisting>
  -
  -        <para>
  -            If interceptor ordering is important (it usually is), you can add
  -            <literal>@Interceptor</literal> annotations to your interceptor 
  -            classes to specify a partial order of interceptors.
  -        </para>
  -        
  -<programlisting><![CDATA[@Interceptor(around={BijectionInterceptor.class,
  -                     ValidationInterceptor.class,
  -                     ConversationInterceptor.class},
  -             within=RemoveInterceptor.class)
  -public class LoggedInInterceptor
  -{
  -    ...
  -}]]></programlisting>
  -
  -        <para>
  -            You can even have a "client-side" interceptor, that runs around any of the built-in
  -            functionality of EJB3:
  -        </para>
  -
  -<programlisting><![CDATA[@Interceptor(type=CLIENT)
  -public class LoggedInInterceptor
  -{
  -    ...
  -}]]></programlisting>
  -
  -        <para>
  -            EJB interceptors are stateful, with a lifecycle that is the same as the component
  -            they intercept. For interceptors which do not need to maintain state, Seam lets
  -            you get a performance optimization by specifying 
  -            <literal>@Interceptor(stateless=true)</literal>.
  -        </para>
  -
  -        <para>
  -            Much of the functionality of Seam is implemented as a set of built-in Seam interceptors,
  -            including the interceptors named in the previous example. You don't have to explicitly 
  -            specify these interceptors by annotating your components; they exist for all interceptable 
  -            Seam components.
  -        </para>
  -        
  -        <para>
  -            You can even use Seam interceptors with JavaBean components, not just EJB3 beans!
  -        </para>
  -        
  +            <title>The <literal>Mutable</literal> interface</title>
           <para>
  -            EJB defines interception not only for business methods (using <literal>@AroundInvoke</literal>),
  -            but also for the lifecycle methods <literal>@PostConstruct</literal>, <literal>@PreDestroy</literal>,
  -            <literal>@PrePassivate</literal> and <literal>@PostActive</literal>. Seam supports all these
  -            lifecycle methods on both component and interceptor not only for EJB3 beans, but also for
  -            JavaBean components (except <literal>@PreDestroy</literal> which is not meaningful for JavaBean
  -            components).
  +                Many application servers feature an amazingly broken implementation of 
  +                <literal>HttpSession</literal> clustering, where changes to the state of mutable
  +                objects bound to the session are only replicated when the application calls
  +                <literal>setAttribute()</literal> explicitly. This is a source of bugs that can
  +                not effectively be tested for at development time, since they will only manifest
  +                when failover occurs. Furthermore, the actual replication message contains the
  +                entire serialized object graph bound to the session attribute, which inefficient.
           </para>
  -
  -    </sect1>
  -    
  -    <sect1>
  -        <title>Asynchronicity</title>
           <para>
  -            Seam makes it very easy to perform work asynchronously from a web request. When most people
  -            think of asynchronicity in Java EE, they think of using JMS. This is certainly one way to
  -            approach the problem in Seam, and is the right way when you have strict and well-defined
  -            quality of service requirements. Seam makes it easy to send and recieve JMS messages using
  -            Seam components (see later chapter).
  +                Of course, EJB stateful session beans must perform automatic dirty checking and 
  +                replication of mutable state and a sophisticated EJB container can introduce
  +                optimizations such as attribute-level replication. Unfortunately, not all Seam
  +                users have the good fortune to be working in an environment that supports EJB 3.0.
  +                So, for session and conversation scoped JavaBean and entity bean components, 
  +                Seam provides an extra layer of cluster-safe state management over the top
  +                of the web container session clustering.
           </para>
           <para>
  -            But for many usecases, JMS is overkill. Seam layers a simple asynchronous method invocation
  -            facility over the EJB 3.0 timer service. In simplest form, this just lets a method call be
  -            processed asynchronously from the caller:
  +                For session or conversation scoped JavaBean components, Seam automatically forces 
  +                replication to occur by calling <literal>setAttribute()</literal> once in every 
  +                request that the component was invoked by the application. Of course, this strategy 
  +                is inefficient for read-mostly components. You can control this behavior by 
  +                implementing the <literal>org.jboss.seam.core.Mutable</literal> interface, or by
  +                extending <literal>org.jboss.seam.core.AbstractMutable</literal>, and writing
  +                your own dirty-checking logic inside the component. For example,
           </para>
           
  -        <programlisting><![CDATA[@Stateless
  - at Name("paymentHandler")
  -public class PaymentHandler
  -{
  -    @Asynchronous
  -    public void processPayment(Payment payment)
  -    {
  -        //do some work!
  -    }
  -}]]></programlisting>
  -        
  -        <programlisting><![CDATA[@Stateful
  - at Name("paymentAction")
  -public class CreatePaymentAction
  +            <programlisting><![CDATA[@Name("account")
  +public class Account extends AbstractMutable
   {
  -    @In(create=true) PaymentHandler paymentHandler;
  -    @In Bill bill;
  -    
  -    public String pay()
  -    {
  -        paymentHandler.processPayment( new Payment(bill) );
  -        return "success";
  -    }
  -}]]></programlisting>
  -
  -        <para>
  -            The asynchronous method is processed in a completely new event context and does
  -            not have access to the session or conversation context state of the caller. However,
  -            the business process context <emphasis>is</emphasis> propagated.
  -        </para>
  -        
  -        <para>
  -            Asynchronous method calls may be scheduled for later execution using the
  -            <literal>@Duration</literal>, <literal>@Expiration</literal> and
  -            <literal>@IntervalDuration</literal> annotations.
  -        </para>
  +    private BigDecimal balance;
           
  -        <programlisting><![CDATA[@Stateless
  - at Name("paymentHandler")
  -public class PaymentHandler
  -{
  -    @Asynchronous
  -    public void processScheduledPayment(Payment payment, @Expiration date)
  +    public void setBalance(BigDecimal balance)
       {
  -        //do some work!
  +        setDirty(this.balance, balance);
  +        this.balance = balance;
       }
   
  -    @Asynchronous
  -    public void processRecurringPayment(Payment payment, @Expiration date, @IntervalDuration interval)
  +    public BigDecimal getBalance()
       {
  -        //do some work!
  +        return balance;
       }
  -}]]></programlisting>
           
  -        <programlisting><![CDATA[@Stateful
  - at Name("paymentAction")
  -public class CreatePaymentAction
  -{
  -    @In(create=true) PaymentHandler paymentHandler;
  -    @In Bill bill;
  -    
  -    public String schedulePayment()
  -    {
  -        paymentHandler.processScheduledPayment( new Payment(bill), bill.getDueDate() );
  -        return "success";
  -    }
  +    ...
   
  -    public String scheduleRecurringPayment()
  -    {
  -        paymentHandler.processRecurringPayment( new Payment(bill), bill.getDueDate(), ONE_MONTH );
  -        return "success";
  -    }
   }]]></programlisting>
   
           <para>
  -            Both client and server may access the <literal>Timer</literal> object associated with
  -            the invocation.
  +                For session or conversation scoped entity bean components, Seam automatically forces 
  +                replication to occur by calling <literal>setAttribute()</literal> once in every 
  +                request. This strategy is not efficient, so session or conversation scope entity
  +                beans should be used with care. You can always write a stateful session bean
  +                or JavaBean component to "manage" the entity bean instance. For example,
           </para>
   
  -        <programlisting><![CDATA[@Stateless
  - at Name("paymentHandler")
  -public class PaymentHandler
  -{
  -    @In Timer timer;
  -    
  -    @Asynchronous
  -    public Timer processScheduledPayment(Payment payment, @Expiration date)
  -    {
  -        //do some work!
  -        
  -        return timer; //note that return value is completely ignored
  -    }
  -
  -}]]></programlisting>
  -        
           <programlisting><![CDATA[@Stateful
  - at Name("paymentAction")
  -public class CreatePaymentAction
  + at Name("account")
  +public class AccountManager extends AbstractMutable
   {
  -    @In(create=true) PaymentHandler paymentHandler;
  -    @In Bill bill;
  +    private Account account; // an entity bean
       
  -    public String schedulePayment()
  +    @Unwrap
  +    public void getAccount()
       {
  -        Timer timer = paymentHandler.processScheduledPayment( new Payment(bill), bill.getDueDate() );
  -        return "success";
  -    }
  -}]]></programlisting>
  -
  -        <para>
  -            Asynchronous methods cannot return any other value to the caller.
  -        </para>
  -
  -        <para>
  -            Of course, Asynchronous method calls have the same quality of service expectations as the
  -            container's EJB timer service.
  -        </para>
  -
  -    </sect1>
  -    
  -    <sect1>
  -        <title>Seam events</title>
  -        <para>
  -            The Seam component model was developed for use with <emphasis>event-driven 
  -            applications</emphasis>, specifically to enable the development of fine-grained, 
  -            loosely-coupled components in a fine-grained eventing model. Events in Seam come
  -            in several types, most of which we have already seen:
  -        </para>
  -        
  -        <itemizedlist>
  -            <listitem>
  -                <para>JSF events</para>
  -            </listitem>
  -            <listitem>
  -                <para>jBPM transition events</para>
  -            </listitem>
  -            <listitem>
  -                <para>Seam page actions</para>
  -            </listitem>
  -            <listitem>
  -                <para>Seam component-driven events</para>
  -            </listitem>
  -            <listitem>
  -                <para>Seam contextual events</para>
  -            </listitem>
  -        </itemizedlist>
  -        
  -        <para>
  -            All of these various kinds of events are mapped to Seam components via JSF EL
  -            method binding expressions. For a JSF event, this is defined in the JSF template:
  -        </para>
  -        
  -        <programlisting><![CDATA[<h:commandButton value="Click me!" action="#{helloWorld.sayHello}"/>]]></programlisting>
  -        
  -        <para>
  -            For a jBPM transition event, it is specified in the jBPM process definition or
  -            pageflow definition:
  -        </para>
  -        
  -        <programlisting><![CDATA[<start-page name="hello" view-id="/hello.jsp">
  -    <transition to="hello">
  -        <action expression="#{helloWorld.sayHello}"/>
  -    </transition>
  -</start-page>]]></programlisting>
  -
  -        <para>
  -            You can find out more information about JSF events and jBPM events elsewhere. 
  -            Lets concentrate for now upon the two additional kinds of events defined by Seam.
  -        </para>
  -        
  -        <sect2>
  -            <title>Page actions</title>
  -
  -        <para>
  -            A Seam page action is an event that occurs just before we render a page. 
  -            We declare page actions in <literal>WEB-INF/pages.xml</literal>. We
  -            can define a page action for either a particular JSF view id:
  -        </para>
  -
  -        <programlisting><![CDATA[<pages>
  -    <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"/>
  -<pages>]]></programlisting>
  -
  -        <para>
  -            Or we can use a wildcard to specify an action that applies to all 
  -            view ids that match the pattern:
  -        </para>
  -
  -        <programlisting><![CDATA[<pages>
  -    <page view-id="/hello/*" action="#{helloWorld.sayHello}"/>
  -<pages>]]></programlisting>
  -
  -        <para>
  -            If multiple wildcarded page actions match the current view-id, Seam
  -            will call all the actions, in order of least-specific to most-specific.
  -        </para>
  -
  -        <para>
  -            The page action method can return a JSF outcome. If the outcome is
  -            non-null, Seam will delegate to the defined JSF navigation rules and
  -            a different view may end up being rendered.
  -        </para>
  -        
  -        <para>
  -            Furthermore, the view id mentioned in the <literal>&lt;page&gt;</literal>
  -            element need not correspond to a real JSP or Facelets page! So, we can
  -            reproduce the functionality of a traditional action-oriented framework
  -            like Struts or WebWork using page actions. For example:
  -        </para>
  -        
  -        <programlisting><![CDATA[TODO: translate struts action into page action]]></programlisting>
  -        
  -        <para>
  -            This is quite useful if you want to do complex things in response to non-faces
  -            requests (for example, HTTP GET requests).
  -        </para>
  -
  -        </sect2>
  -        
  -        <sect2>
  -            <title>Component-driven events</title>
  -            
  -            <para>
  -                Seam components can interact by simply calling each others methods.
  -                Stateful components may even implement the observer/observable pattern.
  -                But to enable components to interact in a more loosely-coupled fashion
  -                than is possible when the components call each others methods directly,
  -                Seam provides <emphasis>component-driven events</emphasis>.
  -            </para>
  -            
  -            <para>
  -                We specify event listeners (observers) in <literal>WEB-INF/events.xml</literal>.
  -            </para>
  -            
  -        <programlisting><![CDATA[<events>
  -    <event type="hello">
  -        <action expression="#{helloListener.sayHelloBack}"/>
  -        <action expression="#{logger.logHello}"/>
  -    </event>
  -<events>]]></programlisting>
  -
  -            <para>
  -                Where the <emphasis>event type</emphasis> is just an arbitrary string.
  -            </para>
  -            
  -            <para>
  -                When an event occurs, the actions registered for that event will be called
  -                in the order they appear in <literal>events.xml</literal>. How does a
  -                component raise an event? Seam provides a built-in component for this.
  -            </para>
  -            
  -            <programlisting><![CDATA[@Name("helloWorld")
  -public class HelloWorld {
  -    public void sayHello() {
  -        FacesMessages.instance().add("Hello World!");
  -        Events.instance().raiseEvent("hello");
  -    }
  -}]]></programlisting>
  -
  -            <para>
  -                Notice that this event producer has no dependency upon event consumers.
  -                The event listener may now be implemented with absolutely no dependency
  -                upon the producer:
  -            </para>
  -
  -            <programlisting><![CDATA[@Name("helloListener")
  -public class HelloListener {
  -    public void sayHelloBack() {
  -        FacesMessages.instance().add("Hello to you too!");
  +        return account;
       }
  -}]]></programlisting>
   
  -            <para>
  -                If you don't like the <literal>events.xml</literal> file, we can use an
  -                annotation instead:
  -            </para>
  +    ...
   
  -            <programlisting><![CDATA[@Name("helloListener")
  -public class HelloListener {
  -    @Observer("hello")
  -    public void sayHelloBack() {
  -        FacesMessages.instance().add("Hello to you too!");
  -    }
   }]]></programlisting>
   
               <para>
  -                You might wonder why I've not mentioned anything about event objects in
  -                this discussion. In Seam, there is no need for an event object to propagate
  -                state between event producer and listener. All state is held in the Seam
  -                contexts, and is shared between components.
  -            </para>
  -            
  -        </sect2>
  -        
  -        <sect2>
  -            <title>Contextual events</title>
  -            <para>
  -                Seam defines a number of built-in events that the application can use to
  -                perform special kinds of framework integration. The events are:
  -            </para>
  -            
  -            <itemizedlist>
  -            <listitem><para><literal>org.jboss.seam.preSetVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is set</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.postSetVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is set</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.preRemoveVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is unset</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.postRemoveVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is unset</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.preDestroyContext.&lt;SCOPE&gt;</literal> &mdash; called before the &lt;SCOPE&gt; context is destroyed</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.postDestroyContext.&lt;SCOPE&gt;</literal> &mdash; called after the &lt;SCOPE&gt; context is destroyed</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.beginConversation </literal>&mdash; called whenever a long-running conversation begins</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.endConversation </literal>&mdash; called whenever a long-running conversation ends</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.beginPageflow.&lt;name&gt; </literal>&mdash; called when the pageflow &lt;name&gt; begins</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.endPageflow.&lt;name&gt; </literal>&mdash; called when the pageflow &lt;name&gt; ends</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.createProcess.&lt;name&gt; </literal>&mdash; called when the process &lt;name&gt; is created</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.endProcess.&lt;name&gt; </literal>&mdash; called when the process &lt;name&gt; ends</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.initProcess.&lt;name&gt; </literal>&mdash; called when the process &lt;name&gt; is associated with the conversation</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.initTask.&lt;name&gt; </literal>&mdash; called when the task &lt;name&gt; is associated with the conversation</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.startTask.&lt;name&gt; </literal>&mdash; called when the task &lt;name&gt; is started</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.endTask.&lt;name&gt; </literal>&mdash; called when the task &lt;name&gt; is ended</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.postCreate.&lt;name&gt; </literal>&mdash; called when the component &lt;name&gt; is created</para></listitem>
  -            <listitem><para><literal>org.jboss.seam.preDestroy.&lt;name&gt; </literal>&mdash; called when the component &lt;name&gt; is destroyed</para></listitem>
  -             </itemizedlist>
  -             
  -             <para>
  -                 Seam components may observe any of these events in just the same way they
  -                 observe component-driven events.
  +                Note that the <literal>EntityHome</literal> class in the Seam Framework provides
  +                a great example of this pattern.
                </para>
  -        </sect2>
           
       </sect1>
       
  @@ -1672,37 +1244,6 @@
       </sect1>
       
       <sect1>
  -        <title>Lifecycle methods</title>
  -        <para>
  -            Session bean and entity bean Seam components support all the usual EJB 3.0 lifecycle
  -            callback (<literal>@PostConstruct</literal>, <literal>@PreDestroy</literal>, etc).
  -            Seam extends all of these callbacks except <literal>@PreDestroy</literal> to JavaBean
  -            components. But Seam also defines its own component lifecycle callbacks.
  -        </para>
  -        <para>
  -            The <literal>@Create</literal> method is called every time Seam instantiates a
  -            component. Unlike the <literal>@PostConstruct</literal> method, this method is
  -            called after the component is fully constructed by the EJB container, and has
  -            access to all the usual Seam functionality (bijection, etc). Components may
  -            define only one <literal>@Create</literal> method.
  -        </para>
  -        <para>
  -            The <literal>@Destroy</literal> method is called when the context that the Seam
  -            component is bound to ends. Components may define only one <literal>@Destroy</literal> 
  -            method. Stateful session bean components <emphasis>must</emphasis> define a method
  -            annotated <literal>@Destroy @Remove</literal>.
  -        </para>
  -        <para>
  -            Finally, a related annotation is the <literal>@Startup</literal> annotation, which
  -            may be applied to any application or session scoped component. The 
  -            <literal>@Startup</literal> annotation tells Seam to instantiate the component
  -            immediately, when the context begins, instead of waiting until it is first 
  -            referenced by a client. It is possible to control the order of instantiation
  -            of startup components by specifying <literal>@Startup(depends={....})</literal>.
  -        </para>
  -    </sect1>
  -    
  -    <sect1>
           <title>Factory and manager components</title>
           <para>
               We often need to work with objects that are not Seam components. But we still want
  
  
  
  1.4       +50 -0     jboss-seam/doc/reference/en/modules/controls.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: controls.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/controls.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -b -r1.3 -r1.4
  --- controls.xml	14 Jul 2006 18:12:23 -0000	1.3
  +++ controls.xml	16 Oct 2006 11:23:14 -0000	1.4
  @@ -27,6 +27,46 @@
              </listitem>
          </varlistentry>
          <varlistentry>
  +           <term><literal>&lt;s:convertDateTime&gt;</literal></term>
  +           <listitem>
  +               <para>
  +                   Perform date or time conversions in the Seam timezone.
  +               </para>
  +           </listitem>
  +       </varlistentry>
  +       <varlistentry>
  +           <term><literal>&lt;s:decorate&gt;</literal></term>
  +           <listitem>
  +               <para>
  +                   "Decorate" a JSF input field when validation fails.
  +               </para>
  +           </listitem>
  +       </varlistentry>
  +       <varlistentry>
  +           <term><literal>&lt;s:message&gt;</literal></term>
  +           <listitem>
  +               <para>
  +                   "Decorate" a JSF input field with the validation error message.
  +               </para>
  +           </listitem>
  +       </varlistentry>
  +       <varlistentry>
  +           <term><literal>&lt;s:span&gt;</literal></term>
  +           <listitem>
  +               <para>
  +                   Render a HTML <literal>&lt;span&gt;</literal>.
  +               </para>
  +           </listitem>
  +       </varlistentry>
  +       <varlistentry>
  +           <term><literal>&lt;s:div&gt;</literal></term>
  +           <listitem>
  +               <para>
  +                   Render a HTML <literal>&lt;div&gt;</literal>.
  +               </para>
  +           </listitem>
  +       </varlistentry>
  +       <varlistentry>
              <term><literal>&lt;s:cache&gt;</literal></term>
              <listitem>
                  <para>
  @@ -178,6 +218,16 @@
                  </itemizedlist>
              </listitem>
          </varlistentry>
  +       <varlistentry>
  +           <term><literal>&lt;s:selection&gt;</literal></term>
  +           <listitem>
  +               <para>
  +                   Propagate the selected row of a <literal>DataModel</literal> with an 
  +                   output link (or similar JSF control).
  +                   <emphasis>Facelets only.</emphasis>
  +               </para>
  +           </listitem>
  +       </varlistentry>
       </variablelist>
       
   </chapter>
  
  
  
  1.10      +1 -2      jboss-seam/doc/reference/en/modules/drools.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: drools.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/drools.xml,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -b -r1.9 -r1.10
  --- drools.xml	24 Jul 2006 16:21:10 -0000	1.9
  +++ drools.xml	16 Oct 2006 11:23:14 -0000	1.10
  @@ -3,8 +3,7 @@
       
       <para>
           Seam makes it easy to call JBoss Rules (Drools) rulebases from Seam
  -        components or jBPM process definitions. <emphasis>This is an experimental
  -        feature of Seam 1.0.</emphasis>
  +        components or jBPM process definitions.
       </para>
       
       <section>
  
  
  
  1.9       +31 -4     jboss-seam/doc/reference/en/modules/i18n.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: i18n.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/i18n.xml,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -b -r1.8 -r1.9
  --- i18n.xml	14 Jul 2006 17:10:51 -0000	1.8
  +++ i18n.xml	16 Oct 2006 11:23:14 -0000	1.9
  @@ -118,9 +118,18 @@
           <para>
               You can select a different name for the resource bundle by setting
               the Seam configuration property named
  -            <literal>resourceBundle.bundleName</literal>.
  +            <literal>resourceBundle.bundleNames</literal>. You can even specify
  +            a list of resource bundle names to be searched (depth first) for
  +            messages.
           </para>
   
  +        <programlisting><![CDATA[<component name="resourceBundle">
  +    <property name="bundlenames">
  +        <value>mycompany_messages</value>
  +        <value>standard_messages</value>
  +    </property>
  +</component>]]></programlisting>
  +
           <para>
               If you define your labels in this special resource bundle, you'll
               be able to use them without having to type <literal>&lt;f:loadBundle ... /&gt;</literal>
  @@ -178,6 +187,24 @@
       </section>
       
       <section>
  +        <title>Timezones</title>
  +        <para>
  +            There is also a session-scoped instance of <literal>java.util.Timezone</literal>,
  +            named <literal>timezone</literal>, and a Seam component for changing the timezone named
  +            <literal>timezoneSelector</literal>. By default, the timezone is the default timezone of
  +            the server. Unfortunately, the JSF specification says that all dates and times should be 
  +            assumed to be UTC, and displayed as UTC, unless a timezone is explicitly specified using 
  +            <literal>&lt;f:convertDateTime&gt;</literal>. This is an extremely inconvenient default 
  +            behavior.
  +        </para>
  +        <para>
  +            Seam overrides this behavior, and defaults all dates and times to the Seam timezone.
  +            In addition, Seam provides the <literal>&lt;s:convertDateTime&gt;</literal> tag which 
  +            always performs conversions in the Seam timezone.
  +        </para>
  +    </section>
  +    
  +    <section>
           <title>Themes</title>
           <para>
               Seam applications are also very easily skinnable. The theme API is very
  @@ -249,9 +276,9 @@
       <section>
           <title>Persisting locale and theme preferences via cookies</title>
           <para>
  -            Both the locale selector and theme selector support persistence of locale and
  -            theme preference to a cookie. Simply set the <literal>cookieEnabled</literal>
  -            configuration property:
  +            The locale selector, theme selector and timezone selector all support 
  +            persistence of locale and theme preference to a cookie. Simply set the 
  +            <literal>cookieEnabled</literal> configuration property:
           </para>
           
           <programlisting><![CDATA[<component name="themeSelector">
  
  
  
  1.5       +180 -9    jboss-seam/doc/reference/en/modules/jms.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: jms.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/jms.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -b -r1.4 -r1.5
  --- jms.xml	12 Jun 2006 00:56:08 -0000	1.4
  +++ jms.xml	16 Oct 2006 11:23:14 -0000	1.5
  @@ -1,11 +1,181 @@
   <chapter id="jms">
  +    <title>Asynchronicity and messaging</title>
  +    <para>
  +        Seam makes it very easy to perform work asynchronously from a web request. When most people
  +        think of asynchronicity in Java EE, they think of using JMS. This is certainly one way to
  +        approach the problem in Seam, and is the right way when you have strict and well-defined
  +        quality of service requirements. Seam makes it easy to send and recieve JMS messages using
  +        Seam components.
  +    </para>
  +    
  +    <para>
  +        But for many usecases, JMS is overkill. Seam layers a simple asynchronous method and event
  +        facility over the EJB 3.0 timer service.
  +    </para>
  +        
  +    <sect1>
  +        <title>Asynchronicity</title>
  +
  +        <para>
  +            Asynchronous events and method calls have the same quality of service expectations as the 
  +            container's EJB timer service. If you're not familiar with the Timer service, don't worry,
  +            you don't need to interact with it directly if you want to use asynchronous methods in
  +            Seam.
  +        </para>
  +        
  +        <para>
  +            Note that this functionality is not available in environments which do not support EJB 3.0.
  +        </para>
  +        
  +        <sect2>
  +        <title>Asynchronous methods</title>
  +        
  +        <para>
  +            In simplest form, an asycnhronous call just lets a method call be processed asynchronously 
  +            (in a different thread) from the caller. We usually use an asynchronous call when we want 
  +            to return an immediate response to the client, and let some expensive work be processed in
  +            the background. This pattern works very well in applications which use AJAX, where the
  +            client can automatically poll the server for the result of the work.
  +        </para>
  +        
  +        <programlisting><![CDATA[@Stateless
  + at Name("paymentHandler")
  +public class PaymentHandler
  +{
  +    @Asynchronous
  +    public void processPayment(Payment payment)
  +    {
  +        //do some work!
  +    }
  +}]]></programlisting>
  +        
  +        <programlisting><![CDATA[@Stateful
  + at Name("paymentAction")
  +public class CreatePaymentAction
  +{
  +    @In(create=true) PaymentHandler paymentHandler;
  +    @In Bill bill;
  +    
  +    public String pay()
  +    {
  +        paymentHandler.processPayment( new Payment(bill) );
  +        return "success";
  +    }
  +}]]></programlisting>
  +
  +        <para>
  +            The asynchronous method is processed in a completely new event context and does
  +            not have access to the session or conversation context state of the caller. However,
  +            the business process context <emphasis>is</emphasis> propagated.
  +        </para>
  +        
  +        <para>
  +            Asynchronous method calls may be scheduled for later execution using the
  +            <literal>@Duration</literal>, <literal>@Expiration</literal> and
  +            <literal>@IntervalDuration</literal> annotations.
  +        </para>
  +        
  +        <programlisting><![CDATA[@Stateless
  + at Name("paymentHandler")
  +public class PaymentHandler
  +{
  +    @Asynchronous
  +    public void processScheduledPayment(Payment payment, @Expiration date)
  +    {
  +        //do some work!
  +    }
  +
  +    @Asynchronous
  +    public void processRecurringPayment(Payment payment, @Expiration date, @IntervalDuration interval)
  +    {
  +        //do some work!
  +    }
  +}]]></programlisting>
  +        
  +        <programlisting><![CDATA[@Stateful
  + at Name("paymentAction")
  +public class CreatePaymentAction
  +{
  +    @In(create=true) PaymentHandler paymentHandler;
  +    @In Bill bill;
  +    
  +    public String schedulePayment()
  +    {
  +        paymentHandler.processScheduledPayment( new Payment(bill), bill.getDueDate() );
  +        return "success";
  +    }
  +
  +    public String scheduleRecurringPayment()
  +    {
  +        paymentHandler.processRecurringPayment( new Payment(bill), bill.getDueDate(), ONE_MONTH );
  +        return "success";
  +    }
  +}]]></programlisting>
  +
  +        <para>
  +            Both client and server may access the <literal>Timer</literal> object associated with
  +            the invocation.
  +        </para>
  +
  +        <programlisting><![CDATA[@Stateless
  + at Name("paymentHandler")
  +public class PaymentHandler
  +{
  +    @In Timer timer;
  +    
  +    @Asynchronous
  +    public Timer processScheduledPayment(Payment payment, @Expiration date)
  +    {
  +        //do some work!
  +        
  +        return timer; //note that return value is completely ignored
  +    }
  +
  +}]]></programlisting>
  +        
  +        <programlisting><![CDATA[@Stateful
  + at Name("paymentAction")
  +public class CreatePaymentAction
  +{
  +    @In(create=true) PaymentHandler paymentHandler;
  +    @In Bill bill;
  +    
  +    public String schedulePayment()
  +    {
  +        Timer timer = paymentHandler.processScheduledPayment( new Payment(bill), bill.getDueDate() );
  +        return "success";
  +    }
  +}]]></programlisting>
  +
  +        <para>
  +            Asynchronous methods cannot return any other value to the caller.
  +        </para>
  +
  +        </sect2>
  +        
  +        <sect2>
  +            <title>Asynchronous events</title>
  +            <para>
  +                Component-driven events may also be asynchronous. To raise an event for asynchronous
  +                processing, simply call the <literal>raiseAsynchronousEvent()</literal> methods of 
  +                the <literal>Events</literal> class. To schedule a timed event, call one of the 
  +                <literal>raiseTimedEvent()</literal> methods. Components may observe asynchronous
  +                events in the usual way, but remember that only the business process context is
  +                propagated to the asynchronous thread.
  +            </para>
  +        </sect2>
  +
  +    </sect1>
  +    
  +    <sect1>
       <title>Messaging in Seam</title>
  +    
       <para>
           Seam makes it easy to send and receive JMS messages to and from
           Seam components.
       </para>
       
  -    <section>
  +    <sect2>
           <title>Configuration</title>
           <para>
               To configure Seam's infrastructure for sending JMS messages,
  @@ -41,9 +211,9 @@
       <property name="queueJndiName">queue/paymentQueue</property>
   </component>]]></programlisting>
   
  -    </section>
  +    </sect2>
   
  -    <section>
  +    <sect2>
           <title>Sending messages</title>
           <para>
               Now, you can inject a JMS <literal>TopicPublisher</literal> and
  @@ -84,23 +254,24 @@
         } 
   }]]></programlisting>
   
  -    </section>
  +    </sect2>
       
  -    <section>
  +    <sect2>
           <title>Receiving messages using a message-driven bean</title>
           <para>
               You can process messages using any EJB3 message driven bean. Message-driven
               beans may even be Seam components, in which case it is possible to inject
               other event and application scoped Seam components.
           </para>
  -    </section>
  +    </sect2>
       
  -    <section>
  +    <sect2>
           <title>Receiving messages in the client</title>
           <para>
               Seam Remoting lets you subscribe to a JMS topic from client-side JavaScript. This is
               described in the next chapter.
           </para>
  -    </section>
  +    </sect2>
       
  +    </sect1>
   </chapter>
  
  
  
  1.1      date: 2006/10/16 11:23:14;  author: gavin;  state: Exp;jboss-seam/doc/reference/en/modules/events.xml
  
  Index: events.xml
  ===================================================================
  <chapter id="events">
      <title>Events and interceptors</title>
  
      <para>
          Complementing the contextual component model, there are two further basic concepts
          that facilitate the extreme loose-coupling that is the distinctive feature of Seam 
          applications. The first is a strong event model where events may be mapped to event 
          listeners via JSF-like method binding expressions. The second is the pervasive use 
          of annotations and interceptors to apply cross-cutting concerns to components which 
          implement business logic.
      </para>
  
      <sect1>
          <title>Seam events</title>
          <para>
              The Seam component model was developed for use with <emphasis>event-driven 
              applications</emphasis>, specifically to enable the development of fine-grained, 
              loosely-coupled components in a fine-grained eventing model. Events in Seam come
              in several types, most of which we have already seen:
          </para>
          
          <itemizedlist>
              <listitem>
                  <para>JSF events</para>
              </listitem>
              <listitem>
                  <para>jBPM transition events</para>
              </listitem>
              <listitem>
                  <para>Seam page actions</para>
              </listitem>
              <listitem>
                  <para>Seam component-driven events</para>
              </listitem>
              <listitem>
                  <para>Seam contextual events</para>
              </listitem>
          </itemizedlist>
          
          <para>
              All of these various kinds of events are mapped to Seam components via JSF EL
              method binding expressions. For a JSF event, this is defined in the JSF template:
          </para>
          
          <programlisting><![CDATA[<h:commandButton value="Click me!" action="#{helloWorld.sayHello}"/>]]></programlisting>
          
          <para>
              For a jBPM transition event, it is specified in the jBPM process definition or
              pageflow definition:
          </para>
          
          <programlisting><![CDATA[<start-page name="hello" view-id="/hello.jsp">
      <transition to="hello">
          <action expression="#{helloWorld.sayHello}"/>
      </transition>
  </start-page>]]></programlisting>
  
          <para>
              You can find out more information about JSF events and jBPM events elsewhere. 
              Lets concentrate for now upon the two additional kinds of events defined by Seam.
          </para>
          
          <sect2>
              <title>Page actions</title>
  
          <para>
              A Seam page action is an event that occurs just before we render a page. 
              We declare page actions in <literal>WEB-INF/pages.xml</literal>. We
              can define a page action for either a particular JSF view id:
          </para>
  
          <programlisting><![CDATA[<pages>
      <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"/>
  <pages>]]></programlisting>
  
          <para>
              Or we can use a wildcard to specify an action that applies to all 
              view ids that match the pattern:
          </para>
  
          <programlisting><![CDATA[<pages>
      <page view-id="/hello/*" action="#{helloWorld.sayHello}"/>
  <pages>]]></programlisting>
  
          <para>
              If multiple wildcarded page actions match the current view-id, Seam
              will call all the actions, in order of least-specific to most-specific.
          </para>
  
          <para>
              The page action method can return a JSF outcome. If the outcome is
              non-null, Seam will delegate to the defined JSF navigation rules and
              a different view may end up being rendered.
          </para>
          
          <para>
              Furthermore, the view id mentioned in the <literal>&lt;page&gt;</literal>
              element need not correspond to a real JSP or Facelets page! So, we can
              reproduce the functionality of a traditional action-oriented framework
              like Struts or WebWork using page actions. For example:
          </para>
          
          <programlisting><![CDATA[TODO: translate struts action into page action]]></programlisting>
          
          <para>
              This is quite useful if you want to do complex things in response to non-faces
              requests (for example, HTTP GET requests).
          </para>
          
          <sect3>
              <title>Page parameters</title>
              <para>
                  A JSF faces request (a form submission) encapsulates both an "action"
                  (a method binding) and "parameters" (input value bindings). A page 
                  action might also needs parameters!
              </para>
              <para>
                  Since GET requests are bookmarkable, page parameters are passed as 
                  human-readable request parameters. (Unlike JSF form inputs, which are
                  anything but!) 
              </para>
              <para>
                  Seam lets us provide a value binding that maps a named request parameter 
                  to an attribute of a model object.
              </para>
              
          <programlisting><![CDATA[<pages>
      <page view-id="/hello.jsp" action="#{helloWorld.sayHello}">
          <param name="firstName" value="#{person.firstName}"/>
          <param name="lastName" value="#{person.lastName}"/>
      </page>
  <pages>]]></programlisting>
  
              <para>
                  The <literal>&lt;param&gt;</literal> declaration is bidirectional, just
                  like a value binding for a JSF input:
              </para>
              
              <itemizedlist>
                  <listitem>
                      <para>
                          When a non-faces (GET) request for the view id occurs, Seam sets 
                          the value of the named request parameter onto the model object, 
                          after performing appropriate type conversions.
                      </para>
                  </listitem>
                  <listitem>
                      <para>
                          Any <literal>&lt;s:link&gt;</literal> transparently includes the
                          request parameter. The value of the parameter is determined by 
                          evaluating the value binding during the render phase (when the 
                          <literal>&lt;s:link&gt;</literal> is rendered).
                      </para>
                  </listitem>
                  <listitem>
                      <para>
                          Any navigation rule with a <literal>&lt;redirect/&gt;</literal> to
                          the view id transparently includes the request parameter. The value 
                          of the parameter is determined by evaluating the value binding at
                          the end of the invoke application phase.
                      </para>
                  </listitem>
                  <listitem>
                      <para>
                          The value is transparently propagated with any JSF form submission
                          for the page with the given view id. (This means that view parameters
                          behave like <literal>PAGE</literal>-scoped context variables for
                          faces requests.
                      </para>
                  </listitem>
              </itemizedlist>
              
              <para>
                  The essential idea behind all this is that <emphasis>however</emphasis>
                  we get from any other page to <literal>/hello.jsp</literal> (or from 
                  <literal>/hello.jsp</literal> back to <literal>/hello.jsp</literal>), 
                  the value of the model attribute referred to in the value binding is
                  "remembered", without the need for a conversation (or other server-side
                  state).
              </para>
              
              <para>
                  This all sounds pretty complex, and you're probably wondering if such an
                  exotic construct is really worth the effort. Actually, the idea is very
                  natural once you "get it". It is definitely worth taking the time to 
                  understand this stuff. Page parameters are the most elegant way to 
                  propagate state across a non-faces request. They are especially cool for 
                  problems like search screens with bookmarkable results pages, where we 
                  would like to be able to write our application code to handle both POST 
                  and GET requests with the same code. Page parameters eliminate repetitive 
                  listing of request parameters in the view definition and make redirects
                  much easier to code.
              </para>
              
              <para>
                  Note that you don't need an actual page action method binding to use
                  a page parameter. The following is perfectly valid:
              </para>
              
              <programlisting><![CDATA[<pages>
      <page view-id="/hello.jsp">
          <param name="firstName" value="#{person.firstName}"/>
          <param name="lastName" value="#{person.lastName}"/>
      </page>
  <pages>]]></programlisting>
  
              <para>
                  You can even specify a JSF converter:
              </para>
  
              <programlisting><![CDATA[<pages>
      <page view-id="/calculator.jsp" action="#{calculator.calculate}">
          <param name="x" value="#{calculator.lhs}"/>
          <param name="y" value="#{calculator.rhs}"/>
          <param name="op" converterId="com.my.calculator.OperatorConverter"/>
      </page>
  <pages>]]></programlisting>
  
              <programlisting><![CDATA[<pages>
      <page view-id="/calculator.jsp" action="#{calculator.calculate}">
          <param name="x" value="#{calculator.lhs}"/>
          <param name="y" value="#{calculator.rhs}"/>
          <param name="op" converter="#{operatorConverter}"/>
      </page>
  <pages>]]></programlisting>
  
          </sect3>
  
          </sect2>
          
          <sect2>
              <title>Component-driven events</title>
              
              <para>
                  Seam components can interact by simply calling each others methods.
                  Stateful components may even implement the observer/observable pattern.
                  But to enable components to interact in a more loosely-coupled fashion
                  than is possible when the components call each others methods directly,
                  Seam provides <emphasis>component-driven events</emphasis>.
              </para>
              
              <para>
                  We specify event listeners (observers) in <literal>WEB-INF/events.xml</literal>.
              </para>
              
          <programlisting><![CDATA[<events>
      <event type="hello">
          <action expression="#{helloListener.sayHelloBack}"/>
          <action expression="#{logger.logHello}"/>
      </event>
  <events>]]></programlisting>
  
              <para>
                  Where the <emphasis>event type</emphasis> is just an arbitrary string.
              </para>
              
              <para>
                  When an event occurs, the actions registered for that event will be called
                  in the order they appear in <literal>events.xml</literal>. How does a
                  component raise an event? Seam provides a built-in component for this.
              </para>
              
              <programlisting><![CDATA[@Name("helloWorld")
  public class HelloWorld {
      public void sayHello() {
          FacesMessages.instance().add("Hello World!");
          Events.instance().raiseEvent("hello");
      }
  }]]></programlisting>
  
              <para>
                  Notice that this event producer has no dependency upon event consumers.
                  The event listener may now be implemented with absolutely no dependency
                  upon the producer:
              </para>
  
              <programlisting><![CDATA[@Name("helloListener")
  public class HelloListener {
      public void sayHelloBack() {
          FacesMessages.instance().add("Hello to you too!");
      }
  }]]></programlisting>
  
              <para>
                  If you don't like the <literal>events.xml</literal> file, we can use an
                  annotation instead:
              </para>
  
              <programlisting><![CDATA[@Name("helloListener")
  public class HelloListener {
      @Observer("hello")
      public void sayHelloBack() {
          FacesMessages.instance().add("Hello to you too!");
      }
  }]]></programlisting>
  
              <para>
                  You might wonder why I've not mentioned anything about event objects in
                  this discussion. In Seam, there is no need for an event object to propagate
                  state between event producer and listener. All state is held in the Seam
                  contexts, and is shared between components.
              </para>
              
          </sect2>
          
          <sect2>
              <title>Contextual events</title>
              <para>
                  Seam defines a number of built-in events that the application can use to
                  perform special kinds of framework integration. The events are:
              </para>
              
              <itemizedlist>
              <listitem><para><literal>org.jboss.seam.preSetVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is set</para></listitem>
              <listitem><para><literal>org.jboss.seam.postSetVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is set</para></listitem>
              <listitem><para><literal>org.jboss.seam.preRemoveVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is unset</para></listitem>
              <listitem><para><literal>org.jboss.seam.postRemoveVariable.&lt;name&gt;</literal> &mdash; called when the context variable &lt;name&gt; is unset</para></listitem>
              <listitem><para><literal>org.jboss.seam.preDestroyContext.&lt;SCOPE&gt;</literal> &mdash; called before the &lt;SCOPE&gt; context is destroyed</para></listitem>
              <listitem><para><literal>org.jboss.seam.postDestroyContext.&lt;SCOPE&gt;</literal> &mdash; called after the &lt;SCOPE&gt; context is destroyed</para></listitem>
              <listitem><para><literal>org.jboss.seam.beginConversation </literal>&mdash; called whenever a long-running conversation begins</para></listitem>
              <listitem><para><literal>org.jboss.seam.endConversation </literal>&mdash; called whenever a long-running conversation ends</para></listitem>
              <listitem><para><literal>org.jboss.seam.beginPageflow.&lt;name&gt; </literal>&mdash; called when the pageflow &lt;name&gt; begins</para></listitem>
              <listitem><para><literal>org.jboss.seam.endPageflow.&lt;name&gt; </literal>&mdash; called when the pageflow &lt;name&gt; ends</para></listitem>
              <listitem><para><literal>org.jboss.seam.createProcess.&lt;name&gt; </literal>&mdash; called when the process &lt;name&gt; is created</para></listitem>
              <listitem><para><literal>org.jboss.seam.endProcess.&lt;name&gt; </literal>&mdash; called when the process &lt;name&gt; ends</para></listitem>
              <listitem><para><literal>org.jboss.seam.initProcess.&lt;name&gt; </literal>&mdash; called when the process &lt;name&gt; is associated with the conversation</para></listitem>
              <listitem><para><literal>org.jboss.seam.initTask.&lt;name&gt; </literal>&mdash; called when the task &lt;name&gt; is associated with the conversation</para></listitem>
              <listitem><para><literal>org.jboss.seam.startTask.&lt;name&gt; </literal>&mdash; called when the task &lt;name&gt; is started</para></listitem>
              <listitem><para><literal>org.jboss.seam.endTask.&lt;name&gt; </literal>&mdash; called when the task &lt;name&gt; is ended</para></listitem>
              <listitem><para><literal>org.jboss.seam.postCreate.&lt;name&gt; </literal>&mdash; called when the component &lt;name&gt; is created</para></listitem>
              <listitem><para><literal>org.jboss.seam.preDestroy.&lt;name&gt; </literal>&mdash; called when the component &lt;name&gt; is destroyed</para></listitem>
               </itemizedlist>
               
               <para>
                   Seam components may observe any of these events in just the same way they
                   observe component-driven events.
               </para>
          </sect2>
          
      </sect1>
      
      <sect1>
        <title>Seam interceptors</title>
        <para>
          EJB 3.0 introduced a standard interceptor model for session bean components. To add an
          interceptor to a bean, you need to write a class with a method annotated 
          <literal>@AroundInvoke</literal> and annotate the bean with an
          <literal>@Interceptors</literal> annotation that specifies the name of the interceptor
          class. For example, the following interceptor checks that the user is logged in before
          allowing invoking an action listener method:
        </para>
        
        <programlisting><![CDATA[public class LoggedInInterceptor {
  
     @AroundInvoke
     public Object checkLoggedIn(InvocationContext invocation) throws Exception {
     
        boolean isLoggedIn = Contexts.getSessionContext().get("loggedIn")!=null;
        if (isLoggedIn) {
           //the user is already logged in
           return invocation.proceed();
        }
        else {
           //the user is not logged in, fwd to login page
           return "login";
        }
     }
  
  }]]></programlisting>
  
      <para>
          To apply this interceptor to a session bean which acts as an action listener, we must
          annotate the session bean <literal>@Interceptors(LoggedInInterceptor.class)</literal>.
          This is a somewhat ugly annotation. Seam builds upon the interceptor framework in
          EJB3 by allowing you to use <literal>@Interceptors</literal> as a meta-annotation. In
          our example, we would create an <literal>@LoggedIn</literal> annotation, as follows:
      </para>
        
        <programlisting><![CDATA[@Target(TYPE)
  @Retention(RUNTIME)
  @Interceptors(LoggedInInterceptor.class)
  public @interface LoggedIn {}]]></programlisting>
  
          <para>
              We can now simply annotate our action listener bean with <literal>@LoggedIn</literal>
              to apply the interceptor.
          </para>
          
          <programlisting><![CDATA[@Stateless
  @Name("changePasswordAction")
  @LoggedIn
  @Interceptors(SeamInterceptor.class)
  public class ChangePasswordAction implements ChangePassword { 
      
      ...
      
      public String changePassword() { ... }
      
  }]]></programlisting>
  
          <para>
              If interceptor ordering is important (it usually is), you can add
              <literal>@Interceptor</literal> annotations to your interceptor 
              classes to specify a partial order of interceptors.
          </para>
          
  <programlisting><![CDATA[@Interceptor(around={BijectionInterceptor.class,
                       ValidationInterceptor.class,
                       ConversationInterceptor.class},
               within=RemoveInterceptor.class)
  public class LoggedInInterceptor
  {
      ...
  }]]></programlisting>
  
          <para>
              You can even have a "client-side" interceptor, that runs around any of the built-in
              functionality of EJB3:
          </para>
  
  <programlisting><![CDATA[@Interceptor(type=CLIENT)
  public class LoggedInInterceptor
  {
      ...
  }]]></programlisting>
  
          <para>
              EJB interceptors are stateful, with a lifecycle that is the same as the component
              they intercept. For interceptors which do not need to maintain state, Seam lets
              you get a performance optimization by specifying 
              <literal>@Interceptor(stateless=true)</literal>.
          </para>
  
          <para>
              Much of the functionality of Seam is implemented as a set of built-in Seam interceptors,
              including the interceptors named in the previous example. You don't have to explicitly 
              specify these interceptors by annotating your components; they exist for all interceptable 
              Seam components.
          </para>
          
          <para>
              You can even use Seam interceptors with JavaBean components, not just EJB3 beans!
          </para>
          
          <para>
              EJB defines interception not only for business methods (using <literal>@AroundInvoke</literal>),
              but also for the lifecycle methods <literal>@PostConstruct</literal>, <literal>@PreDestroy</literal>,
              <literal>@PrePassivate</literal> and <literal>@PostActive</literal>. Seam supports all these
              lifecycle methods on both component and interceptor not only for EJB3 beans, but also for
              JavaBean components (except <literal>@PreDestroy</literal> which is not meaningful for JavaBean
              components).
          </para>
  
      </sect1>
        
  </chapter>
  
  



More information about the jboss-cvs-commits mailing list