<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">

<chapter id="concepts">
    <title>The contextual component model</title>
    <para> 
        The two core concepts in Seam are the notion of a <emphasis>context</emphasis> and the notion of a
        <emphasis>component</emphasis>. Components are stateful objects, usually EJBs, and an instance of a
        component is associated with a context, and given a name in that context. <emphasis>Bijection</emphasis>
        provides a mechanism for aliasing internal component names (instance variables) to contextual names, allowing
        component trees to be dynamically assembled, and reassembled by Seam.
    </para>
    
    <para>
        Let's start by describing the contexts built in to Seam.
    </para>

    <sect1>
        <title>Seam contexts</title>
        <para> Seam contexts are created and destroyed by the framework. The application does not control context
            demarcation via explicit Java API calls. Context are usually implicit. In some cases, however, contexts are
            demarcated via annotations. </para>
        <para> The basic Seam contexts are: </para>

        <itemizedlist>
            <listitem>
                <para> Stateless context </para>
            </listitem>
            <listitem>
                <para> Event (or request) context </para>
            </listitem>
            <listitem>
                <para> Page context </para>
            </listitem>
            <listitem>
                <para> Conversation context </para>
            </listitem>
            <listitem>
                <para> Session context </para>
            </listitem>
            <listitem>
                <para> Business process context </para>
            </listitem>
            <listitem>
                <para> Application context </para>
            </listitem>
        </itemizedlist>

        <para> 
            You will recognize some of these contexts from servlet and related specifications. However, two of them
            might be new to you: <emphasis>conversation context</emphasis>, and <emphasis>business process
            context</emphasis>. One reason state management in web applications is so fragile and error-prone is that
            the three built-in contexts (request, session and application) are not especially meaningful from the point
            of view of the business logic. A user login session, for example, is a fairly arbitrary construct in terms
            of the actual application work flow. Therefore, most Seam components are scoped to the conversation or
            business process contexts, since they are the contexts which are most meaningful in terms of the
            application.
        </para>

        <para>
            Let's look at each context in turn.
        </para>

        <sect2>
            <title>Stateless context</title>
            <para>
                Components which are truly stateless (stateless session beans, primarily) always live in the
                stateless context (this is really a non-context). Stateless components are not very interesting, and are
                arguably not very object-oriented. Nevertheless, they are important and often useful.
            </para>
        </sect2>

        <sect2>
            <title>Event context</title>
            <para>
                The event context is the "narrowest" stateful context, and is a generalization of the notion of the
                web request context to cover other kinds of events. Nevertheless, the event context associated with the
                lifecycle of a JSF request is the most important example of an event context, and the one you will work
                with most often. Components associated with the event context are destroyed at the end of the request,
                but their state is available and well-defined for at least the lifecycle of the request.
            </para>
            <para> 
                When you invoke a Seam component via RMI, or Seam Remoting, the event context is created and
                destroyed just for the invocation.
            </para>
        </sect2>

        <sect2>
            <title>Page context</title>
            <para>
                The page context allows you to associate state with a particular instance of a rendered page. You can
                initialize state in your event listener, or while actually rendering the page, and then have access to
                it from any event that originates from that page. This is especially useful for functionality like
                clickable lists, where the list is backed by changing data on the server side. The state is actually
                serialized to the client, so this construct is extremely robust with respect to multi-window operation
                and the back button.
            </para>
        </sect2>

        <sect2>
            <title>Conversation context</title>
            <para>
                The conversation context is a truly central concept in Seam. A <emphasis>conversation</emphasis> is a
                unit of work from the point of view of the user. It might span several interactions with the user,
                several requests, and several database transactions. But to the user, a conversation solves a single
                problem. For example, "book hotel", "approve contract", "create order" are all conversations. You might
                like to think of a conversation implementing a single "use case" or "user story", but the relationship 
                is not necessarily quite exact.
            </para>
            <para>
                A conversation holds state associated with "what the user is doing now, in this window". A single
                user may have multiple conversations in progress at any point in time, usually in multiple windows. The
                conversation context allows us to ensure that state from the different conversations does not collide
                and cause bugs.
            </para>
            <para>
                It might take you some time to get used to thinking of applications in terms of conversations. But
                once you get used to it, we think you'll love the notion, and never be able to not think in terms of
                conversations again!
            </para>
            <para>
                Some conversations last for just a single request. Conversations that span multiple requests must be
                demarcated using annotations provided by Seam.
            </para>
            <para>
                Some conversations are also <emphasis>tasks</emphasis>. A task is a conversation that is significant
                in terms of a long-running business process, and has the potential to trigger a business process state
                transition when it is successfully completed. Seam provides a special set of annotations for task
                demarcation.
            </para>
            <para>
                Conversations may be <emphasis>nested</emphasis>, with one conversation taking place "inside" a wider
                conversation. This is an advanced feature.
            </para>
            <para>
                Usually, conversation state is actually held by Seam in the servlet session between requests. Seam
                implements configurable <emphasis>conversation timeout</emphasis>, automatically destroying inactive
                conversations, and thus ensuring that the state held by a single user login session does not grow
                without bound if the user abandons conversations.
            </para>
            <para>
                Seam serializes processing of concurrent requests that take place in the same long-running
                conversation context, in the same process.
            </para>
            <para>
                Alternatively, Seam may be configured to keep conversational state in the client browser.
            </para> 
        </sect2>

        <sect2>
            <title>Session context</title>
            <para>
                A session context holds state associated with the user login session. While there are some cases
                where it is useful to share state between several conversations, we generally frown on the use of
                session context for holding components other than global information about the logged in user.
            </para>
            <para> 
                In a JSR-168 portal environment, the session context represents the portlet session. 
            </para>
        </sect2>

        <sect2>
            <title>Business process context</title>
            <para> 
                The business process context holds state associated with the long running business process. This
                state is managed and made persistent by the BPM engine (JBoss jBPM). The business process spans multiple
                interactions with multiple users, so this state is shared between multiple users, but in a well-defined
                manner. The current task determines the current business process instance, and the lifecycle of the
                business process is defined externally using a <emphasis>process definition language</emphasis>, so
                there are no special annotations for business process demarcation. 
            </para>
        </sect2>

        <sect2>
            <title>Application context</title>
            <para> 
                The application context is the familiar servlet context from the servlet spec. Application context is
                mainly useful for holding static information such as configuration data, reference data or metamodels.
                For example, Seam stores its own configuration and metamodel in the application context. 
            </para>
        </sect2>

        <sect2>
            <title>Context variables</title>
            <para> 
                A context defines a namespace, a set of <emphasis>context variables</emphasis>. These work much the
                same as session or request attributes in the servlet spec. You may bind any value you like to a context
                variable, but usually we bind Seam component instances to context variables. 
            </para>

            <para> 
                So, within a context, a component instance is identified by the context variable name (this is
                usually, but not always, the same as the component name). You may programatically access a named
                component instance in a particular scope via the <literal>Contexts</literal> class, which provides
                access to several thread-bound instances of the <literal>Context</literal> interface: 
            </para>

            <programlisting role="JAVA"><![CDATA[User user = (User) Contexts.getSessionContext().get("user");]]></programlisting>

            <para>
                You may also set or change the value associated with a name: 
            </para>

            <programlisting role="JAVA"><![CDATA[Contexts.getSessionContext().set("user", user);]]></programlisting>

            <para> 
                Usually, however, we obtain components from a context via injection, and put component instances into
                a context via outjection. 
            </para>
        </sect2>

        <sect2>
            <title>Context search priority</title>
            <para> 
                Sometimes, as above, component instances are obtained from a particular known scope. Other times, all
                stateful scopes are searched, in <emphasis>priority order</emphasis>. The order is as follows: 
            </para>

            <itemizedlist>
                <listitem>
                    <para> Event context </para>
                </listitem>
                <listitem>
                    <para> Page context </para>
                </listitem>
                <listitem>
                    <para> Conversation context </para>
                </listitem>
                <listitem>
                    <para> Session context </para>
                </listitem>
                <listitem>
                    <para> Business process context </para>
                </listitem>
                <listitem>
                    <para> Application context </para>
                </listitem>
            </itemizedlist>

            <para> 
                You can perform a priority search by calling <literal>Contexts.lookupInStatefulContexts()</literal>.
                Whenever you access a component by name from a JSF page, a priority search occurs. 
            </para>

        </sect2>

        <sect2 id="concurrency">
            <title>Concurrency model</title>
            <para> 
                Neither the servlet nor EJB specifications define any facilities for managing concurrent requests
                originating from the same client. The servlet container simply lets all threads run concurrently and
                leaves enforcing threadsafeness to application code. The EJB container allows stateless components to be
                accessed concurrently, and throws an exception if multiple threads access a stateful session bean. 
            </para>
            <para> 
                This behavior might have been okay in old-style web applications which were based around
                fine-grained, synchronous requests. But for modern applications which make heavy use of many
                fine-grained, asynchronous (AJAX) requests, concurrency is a fact of life, and must be supported by the
                programming model. Seam weaves a concurrency management layer into its context model. 
            </para>
            <para> 
                The Seam session and application contexts are multithreaded. Seam will allow concurrent requests in a
                context to be processed concurrently. The event and page contexts are by nature single threaded. The
                business process context is strictly speaking multi-threaded, but in practice concurrency is
                sufficiently rare that this fact may be disregarded most of the time. Finally, Seam enforces a
                <emphasis>single thread per conversation per process</emphasis> model for the conversation context
                by serializing concurrent requests in the same long-running conversation context. 
            </para>
            <para> 
                Since the session context is multithreaded, and often contains volatile state, session scope
                components are always protected by Seam from concurrent access. Seam serializes requests to session
                scope session beans and JavaBeans by default (and detects and breaks any deadlocks that occur). This is
                not the default behaviour for application scoped components however, since application scoped components
                do not usually hold volatile state and because synchronization at the global level is
                <emphasis>extremely</emphasis> expensive. However, you can force a serialized threading model on any
                session bean or JavaBean component by adding the <literal>@Synchronized</literal> annotation. 
            </para>
            <para> 
                This concurrency model means that AJAX clients can safely use volatile session and conversational
                state, without the need for any special work on the part of the developer.
            </para>
        </sect2>

    </sect1>

    <sect1>
        <title>Seam components</title>
        <para> 
            Seam components are POJOs (Plain Old Java Objects). In particular, they are JavaBeans or EJB 3.0
            enterprise beans. While Seam does not require that components be EJBs and can even be used without an EJB
            3.0 compliant container, Seam was designed with EJB 3.0 in mind and includes deep integration with EJB 3.0.
            Seam supports the following <emphasis>component types</emphasis>. 
        </para>

        <itemizedlist>
            <listitem>
                <para> EJB 3.0 stateless session beans </para>
            </listitem>
            <listitem>
                <para> EJB 3.0 stateful session beans </para>
            </listitem>
            <listitem>
                <para> EJB 3.0 entity beans </para>
            </listitem>
            <listitem>
                <para> JavaBeans </para>
            </listitem>
            <listitem>
                <para> EJB 3.0 message-driven beans </para>
            </listitem>
        </itemizedlist>

        <sect2>
            <title>Stateless session beans</title>
            <para> 
                Stateless session bean components are not able to hold state across multiple invocations. Therefore,
                they usually work by operating upon the state of other components in the various Seam contexts. They may
                be used as JSF action listeners, but cannot provide properties to JSF components for display. 
            </para>
            <para> 
                Stateless session beans always live in the stateless context. 
            </para>
            <para> 
                Stateless session beans can be accessed concurrently as a new instance is used for each request. 
                Assigning the instance to the request is the responsibility of the EJB3 container (normally instances
                will be allocated from a reusable pool meaning that you may find any instance variables contain data
                from previous uses of the bean). 
            </para>
            <para> 
                Stateless session beans are the least interesting kind of Seam component. 
            </para> 
            <para>
                Seam stateless session bean components may be instantiated using <literal>Component.getInstance()</literal>
                or <literal>@In(create=true)</literal>. They should not be directly instantiated via JNDI lookup
                or the <literal>new</literal> operator.
            </para> 
        </sect2>

        <sect2>
            <title>Stateful session beans</title>
            <para> 
                Stateful session bean components are able to hold state not only across multiple invocations of the
                bean, but also across multiple requests. Application state that does not belong in the database should
                usually be held by stateful session beans. This is a major difference between Seam and many other web
                application frameworks. Instead of sticking information about the current conversation directly in the
                <literal>HttpSession</literal>, you should keep it in instance variables of a stateful session bean
                that is bound to the conversation context. This allows Seam to manage the lifecycle of this state for
                you, and ensure that there are no collisions between state relating to different concurrent
                conversations. 
            </para>
            <para> 
                Stateful session beans are often used as JSF action listener, and as backing beans that provide
                properties to JSF components for display or form submission. 
            </para>
            <para> 
                By default, stateful session beans are bound to the conversation context. They may never be bound to
                the page or stateless contexts. 
            </para>
            <para> 
                Concurrent requests to session-scoped stateful session beans are always serialized by Seam. 
            </para>   
            <para>
                Seam stateful session bean components may be instantiated using <literal>Component.getInstance()</literal>
                or <literal>@In(create=true)</literal>. They should not be directly instantiated via JNDI lookup
                or the <literal>new</literal> operator.
            </para> 
        </sect2>

        <sect2>
            <title>Entity beans</title>
            <para> 
                Entity beans may be bound to a context variable and function as a seam component. Because entities
                have a persistent identity in addition to their contextual identity, entity instances are usually bound
                explicitly in Java code, rather than being instantiated implicitly by Seam. 
            </para>
            <para> 
                Entity bean components do not support bijection or context demarcation. Nor does invocation of an
                entity bean trigger validation. 
            </para>
            <para> 
                Entity beans are not usually used as JSF action listeners, but do often function as backing beans
                that provide properties to JSF components for display or form submission. In particular, it is common to
                use an entity as a backing bean, together with a stateless session bean action listener to implement
                create/update/delete type functionality. 
            </para>
            <para>
                By default, entity beans are bound to the conversation context. They may never be bound to the
                stateless context. 
            </para>
            <para> 
                Note that it in a clustered environment is somewhat less efficient to bind an entity bean directly to
                a conversation or session scoped Seam context variable than it would be to hold a reference to the
                entity bean in a stateful session bean. For this reason, not all Seam applications define entity beans
                to be Seam components. 
            </para>
            <para>
                Seam entity bean components may be instantiated using <literal>Component.getInstance()</literal>,
                <literal>@In(create=true)</literal> or directly using the <literal>new</literal> operator.
            </para> 
        </sect2>

        <sect2>
            <title>JavaBeans</title>
            <para> 
                Javabeans may be used just like a stateless or stateful session bean. However, they do not provide
                the functionality of a session bean (declarative transaction demarcation, declarative security,
                efficient clustered state replication, EJB 3.0 persistence, timeout methods, etc). 
            </para>
            <para> 
                In a later chapter, we show you how to use Seam and Hibernate without an EJB container. In this use
                case, components are JavaBeans instead of session beans. Note, however, that in many application servers
                it is somewhat less efficient to cluster conversation or session scoped Seam JavaBean components than it
                is to cluster stateful session bean components. 
            </para>
            <para> 
                By default, JavaBeans are bound to the event context. 
            </para>
            <para> 
                Concurrent requests to session-scoped JavaBeans are always serialized by Seam. 
            </para>
            <para>
                Seam JavaBean components may be instantiated using <literal>Component.getInstance()</literal>
                or <literal>@In(create=true)</literal>. They should not be directly instantiated using the 
                <literal>new</literal> operator.
            </para> 
        </sect2>

        <sect2>
            <title>Message-driven beans</title>
            <para> 
                Message-driven beans may function as a seam component. However, message-driven beans are called quite
                differently to other Seam components - instead of invoking them via the context variable, they listen
                for messages sent to a JMS queue or topic. 
            </para>
            <para> 
                Message-driven beans may not be bound to a Seam context. Nor do they have access to the session or
                conversation state of their "caller". However, they do support bijection and some other Seam
                functionality. 
            </para>
            <para>
                Message-driven beans are never instantiated by the application. They are instantiated by the EJB
                container when a message is received.
            </para>
        </sect2>

        <sect2>
            <title>Interception</title>
            <para> 
                In order to perform its magic (bijection, context demarcation, validation, etc), Seam must intercept
                component invocations. For JavaBeans, Seam is in full control of instantiation of the component, and no
                special configuration is needed. For entity beans, interception is not required since bijection and
                context demarcation are not defined. For session beans, we must register an EJB interceptor for the
                session bean component. We could use an annotation, as follows: 
            </para>

            <programlisting role="JAVA"><![CDATA[@Stateless
@Interceptors(SeamInterceptor.class)
public class LoginAction implements Login { 
    ... 
}]]></programlisting>

            <para> 
                But a much better way is to define the interceptor in <literal>ejb-jar.xml</literal>. 
            </para>

            <programlisting role="XML"><![CDATA[<interceptors>
   <interceptor>
      <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
   </interceptor>
</interceptors>
   
<assembly-descriptor>
   <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
   </interceptor-binding>
</assembly-descriptor>]]></programlisting>

        </sect2>

        <sect2>
            <title>Component names</title>
            <para> 
                All seam components need a name. We can assign a name to a component using the
                <literal>@Name</literal> annotation: 
            </para>

            <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    ... 
}]]></programlisting>

            <para> 
                This name is the <emphasis>seam component name</emphasis> and is not related to any other name
                defined by the EJB specification. However, seam component names work just like JSF managed bean names
                and you can think of the two concepts as identical. 
            </para>

            <para>
                <literal>@Name</literal> is not the only way to define a component name, but we always need
                to specify the name <emphasis>somewhere</emphasis>. If we don't, then none of the other
                Seam annotations will function.
            </para>

            <para> 
                Just like in JSF, a seam component instance is usually bound to a context variable with the same name
                as the component name. So, for example, we would access the <literal>LoginAction</literal> using
                <literal>Contexts.getStatelessContext().get("loginAction")</literal>. In particular, whenever Seam
                itself instantiates a component, it binds the new instance to a variable with the component name.
                However, again like JSF, it is possible for the application to bind a component to some other context
                variable by programmatic API call. This is only useful if a particular component serves more than one
                role in the system. For example, the currently logged in <literal>User</literal> might be bound to the
                <literal>currentUser</literal> session context variable, while a <literal>User</literal> that is the
                subject of some administration functionality might be bound to the <literal>user</literal> conversation
                context variable. 
            </para>

            <para> 
                For very large applications, and for built-in seam components, qualified names are often used. 
            </para>

            <programlisting role="JAVA"><![CDATA[@Name("com.jboss.myapp.loginAction")
@Stateless
public class LoginAction implements Login { 
    ... 
}]]></programlisting>

            <para> 
                We may use the qualified component name both in Java code and in JSF's expression language: 
            </para>

            <programlisting role="XHTML"><![CDATA[<h:commandButton type="submit" value="Login"
                 action="#{com.jboss.myapp.loginAction.login}"/>]]></programlisting>

            <para> 
                Since this is noisy, Seam also provides a means of aliasing a qualified name to a simple name. Add a
                line like this to the <literal>components.xml</literal> file: 
            </para>

            <programlisting role="XML"><![CDATA[<factory name="loginAction" scope="STATELESS" value="#{com.jboss.myapp.loginAction}"/>]]></programlisting>

            <para> 
                All of the built-in Seam components have qualified names, but most of them are aliased to a simple
                name by the <literal>components.xml</literal> file included in the Seam jar. 
            </para>

        </sect2>

        <sect2>
            <title>Defining the component scope</title>
            <para> 
                We can override the default scope (context) of a component using the <literal>@Scope</literal>
                annotation. This lets us define what context a component instance is bound to, when it is instantiated
                by Seam. 
            </para>

            <programlisting role="JAVA"><![CDATA[@Name("user")
@Entity
@Scope(SESSION)
public class User { 
    ... 
}]]></programlisting>

            <para>
                <literal>org.jboss.seam.ScopeType</literal> defines an enumeration of possible scopes.
            </para>

        </sect2>

        <sect2>
            <title>Components with multiple roles</title>
            <para> 
                Some Seam component classes can fulfill more than one role in the system. For example, we often have
                a <literal>User</literal> class which is usually used as a session-scoped component representing the
                current user but is used in user administration screens as a conversation-scoped component. The
                <literal>@Role</literal> annotation lets us define an additional named role for a component, with a
                different scope&#8212;it lets us bind the same component class to different context variables. (Any
                Seam component <emphasis>instance</emphasis> may be bound to multiple context variables, but this lets
                us do it at the class level, and take advantage of auto-instantiation.) 
            </para>

            <programlisting role="JAVA"><![CDATA[@Name("user")
@Entity
@Scope(CONVERSATION)
@Role(name="currentUser", scope=SESSION)
public class User { 
    ... 
}]]></programlisting>

            <para>
                The <literal>@Roles</literal> annotation lets us specify as many additional roles as we like.
            </para>

            <programlisting role="JAVA"><![CDATA[@Name("user")
@Entity
@Scope(CONVERSATION)
@Roles({@Role(name="currentUser", scope=SESSION),
        @Role(name="tempUser", scope=EVENT)})
public class User { 
    ... 
}]]></programlisting>

        </sect2>

        <sect2>
            <title>Built-in components</title>
            <para>
                Like many good frameworks, Seam eats its own dogfood and is implemented mostly as a set of built-in
                Seam interceptors (see later) and Seam components. This makes it easy for applications to interact with
                built-in components at runtime or even customize the basic functionality of Seam by replacing the
                built-in components with custom implementations. The built-in components are defined in the Seam
                namespace <literal>org.jboss.seam.core</literal> and the Java package of the same name.
            </para>
            <para> 
                The built-in components may be injected, just like any Seam components, but they also provide
                convenient static <literal>instance()</literal> methods: 
            </para>
            <programlisting role="JAVA"><![CDATA[FacesMessages.instance().add("Welcome back, #{user.name}!");]]></programlisting>
        </sect2>

    </sect1>

    <sect1>
        <title>Bijection</title>
        <para>
            <emphasis>Dependency injection</emphasis> or <emphasis>inversion of control</emphasis> is by now a familiar
            concept to most Java developers. Dependency injection allows a component to obtain a reference to another
            component by having the container "inject" the other component to a setter method or instance variable. In
            all dependency injection implementations that we have seen, injection occurs when the component is
            constructed, and the reference does not subsequently change for the lifetime of the component instance. For
            stateless components, this is reasonable. From the point of view of a client, all instances of a particular
            stateless component are interchangeable. On the other hand, Seam emphasizes the use of stateful components.
            So traditional dependency injection is no longer a very useful construct. Seam introduces the notion of
            <emphasis>bijection</emphasis> as a generalization of injection. In contrast to injection, bijection is: 
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>contextual</emphasis> - bijection is used to assemble stateful components from various
                    different contexts (a component from a "wider" context may even have a reference to a component from
                    a "narrower" context)
                </para>
            </listitem>
            <listitem>
                <para>
                    <emphasis>bidirectional</emphasis> - values are injected from context variables into attributes of
                    the component being invoked, and also <emphasis>outjected</emphasis> from the component attributes
                    back out to the context, allowing the component being invoked to manipulate the values of contextual
                    variables simply by setting its own instance variables 
                </para>
            </listitem>
            <listitem>
                <para>
                    <emphasis>dynamic</emphasis> - since the value of contextual variables changes over time, and since
                    Seam components are stateful, bijection takes place every time a component is invoked 
                </para>
            </listitem>
        </itemizedlist>

        <para> 
            In essence, bijection lets you alias a context variable to a component instance variable, by specifying
            that the value of the instance variable is injected, outjected, or both. Of course, we use annotations to
            enable bijection.
        </para>

        <para> 
            The <literal>@In</literal> annotation specifies that a value should be injected, either into an instance
            variable: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    @In User user;
    ... 
}]]></programlisting>

        <para> 
            or into a setter method: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    User user;
    
    @In
    public void setUser(User user) {
        this.user=user;
    }
    
    ... 
}]]></programlisting>


        <para> 
            By default, Seam will do a priority search of all contexts, using the name of the property or instance
            variable that is being injected. You may wish to specify the context variable name explicitly, using, for
            example, <literal>@In("currentUser")</literal>. 
        </para>

        <para> 
            If you want Seam to create an instance of the component when there is no existing component instance
            bound to the named context variable, you should specify <literal>@In(create=true)</literal>. If the value is
            optional (it can be null), specify <literal>@In(required=false)</literal>. 
        </para>
        
        <para>
            For some components, it can be repetitive to have to specify <literal>@In(create=true)</literal> everywhere
            they are used. In such cases, you can annotate the component <literal>@AutoCreate</literal>, and then it
            will always be created, whenever needed, even without the explicit use of <literal>create=true</literal>.
        </para>

        <para> 
            You can even inject the value of an expression: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    @In("#{user.username}") String username;
    ... 
}]]></programlisting>

        <para>
            Injected values are disinjected (i.e, set to <literal>null</literal>) immediately after method 
            completion and outjection.
        </para>
        
        <para> 
            (There is much more information about component lifecycle and injection in the next chapter.) 
        </para>

        <para> 
            The <literal>@Out</literal> annotation specifies that an attribute should be outjected, either from an
            instance variable: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    @Out User user;
    ... 
}]]></programlisting>

        <para> 
            or from a getter method: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    User user;
    
    @Out
    public User getUser() {
        return user;
    }
    
    ... 
}]]></programlisting>

        <para> 
            An attribute may be both injected and outjected: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    @In @Out User user;
    ... 
}]]></programlisting>

        <para> 
            or: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("loginAction")
@Stateless
public class LoginAction implements Login { 
    User user;
    
    @In
    public void setUser(User user) {
        this.user=user;
    }
    
    @Out
    public User getUser() {
        return user;
    }
    
    ... 
}]]></programlisting>

    </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). But Seam also supports 
            the use of any of these callbacks with JavaBean components. However, since these annotations are
            not available in a J2EE environment, Seam defines two additional component lifecycle callbacks,
            equivalent to <literal>@PostConstruct</literal> and <literal>@PreDestroy</literal>.
        </para>
        
        <para> 
            The <literal>@Create</literal> method is called after Seam instantiates a component. 
            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.
        </para>
        
        <para>
            In addition, stateful session bean components <emphasis>must</emphasis> define a method with no parameters 
            annotated <literal>@Remove</literal>. This method is called by Seam when the context ends.
        </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>Conditional installation</title>
        
        <para>
            The <literal>@Install</literal> annotation lets you control conditional installation of components that
            are required in some deployment scenarios and not in others. This is useful if:
        </para>
        
        <itemizedlist>
        	<listitem>
        		<para>
        		    You want to mock out some infrastructural component in tests.
        		</para>
        	</listitem>
        	<listitem>
        		<para>
        		    You want change the implementation of a component in certain
        		    deployment scenarios.
        		</para>
        	</listitem>
        	<listitem>
        		<para>
        		    You want to install some components only if their dependencies are
        		    available (useful for framework authors).
        		</para>
        	</listitem>
        </itemizedlist>
        
        <para>
            <literal>@Install</literal> works by letting you specify <emphasis>precedence</emphasis>
            and <emphasis>dependencies</emphasis>. 
        </para>
        
        <para>
            The precedence of a component is a number that Seam uses to decide which component to
            install when there are multiple classes with the same component name in the classpath.
            Seam will choose the component with the higher precendence. There are some predefined
            precedence values (in ascending order):
        </para>
        
        <orderedlist>
        	<listitem>
        		<para>
        		    <literal>BUILT_IN</literal> &#8212; the lowest precedece components are
        		    the components built in to Seam. 
        		</para>
        	</listitem>
        	<listitem>
        		<para>
        		    <literal>FRAMEWORK</literal> &#8212; components defined by third-party 
        		    frameworks may override built-in components, but are overridden by
        		    application components. 
        		</para>
        	</listitem>
        	<listitem>
        		<para>
        		    <literal>APPLICATION</literal> &#8212; the default precedence. This is 
                    appropriate for most application components.
        		</para>
        	</listitem>
        	<listitem>
        		<para>
        		    <literal>DEPLOYMENT</literal> &#8212; for application components which
        		    are deployment-specific. 
        		</para>
        	</listitem>
        	<listitem>
        		<para>
        		    <literal>MOCK</literal> &#8212; for mock objects used in testing. 
        		</para>
        	</listitem>
        </orderedlist>
        
        <para>
            Suppose we have a component named <literal>messageSender</literal> that talks to
            a JMS queue. 
        </para>
        
        <programlisting role="JAVA"><![CDATA[@Name("messageSender") 
public class MessageSender {
    public void sendMessage() {
        //do something with JMS
    }
}]]></programlisting>
        
        <para>
            In our unit tests, we don't have a JMS queue available, so we would like to stub
            out this method. We'll create a <emphasis>mock</emphasis> component that exists
            in the classpath when unit tests are running, but is never deployed with the
            application:
        </para>
        
        <programlisting role="JAVA"><![CDATA[@Name("messageSender") 
@Install(precedence=MOCK)
public class MockMessageSender extends MessageSender {
    public void sendMessage() {
        //do nothing!
    }
}]]></programlisting>

        <para>
            The <literal>precedence</literal> helps Seam decide which version to use when it finds
            both components in the classpath.
        </para>
        
        <para>
            This is nice if we are able to control exactly which classes are in the classpath. But
            if I'm writing a reusable framework with many dependecies, I don't want to have to 
            break that framework across many jars. I want to be able to decide which components
            to install depending upon what other components are installed, and upon what classes
            are available in the classpath. The <literal>@Install</literal> annotation also 
            controls this functionality. Seam uses this mechanism internally to enable conditional 
            installation of many of the built-in components. However, you probably won't need to
            use it in your application.
        </para>
        
    </sect1>

    <sect1>
        <title>Logging</title>
        
        <para> 
            Who is not totally fed up with seeing noisy code like this? 
         </para>

        <programlisting role="JAVA"><![CDATA[private static final Log log = LogFactory.getLog(CreateOrderAction.class);
        
public Order createOrder(User user, Product product, int quantity) {
    if ( log.isDebugEnabled() ) {
        log.debug("Creating new order for user: " + user.username() + 
            " product: " + product.name() 
            + " quantity: " + quantity);
    }
    return new Order(user, product, quantity);
}]]></programlisting>

        <para> 
            It is difficult to imagine how the code for a simple log message could possibly be more verbose. There is
            more lines of code tied up in logging than in the actual business logic! I remain totally astonished that
            the Java community has not come up with anything better in 10 years. 
        </para>

        <para> 
            Seam provides a logging API that simplifies this code significantly: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Logger private Log log;
        
public Order createOrder(User user, Product product, int quantity) {
    log.debug("Creating new order for user: #0 product: #1 quantity: #2", user.username(), product.name(), quantity);
    return new Order(user, product, quantity);
}]]></programlisting>

        <para>
            It doesn't matter if you declare the <literal>log</literal> variable static or not&#8212;it will work 
            either way, except for entity bean components which require the <literal>log</literal> variable to be
            static.
        </para>

        <para> 
            Note that we don't need the noisy <literal>if ( log.isDebugEnabled() )</literal> guard, since string
            concatenation happens <emphasis>inside</emphasis> the <literal>debug()</literal> method. Note also that we
            don't usually need to specify the log category explicitly, since Seam knows what component it is injecting
            the <literal>Log</literal> into. 
        </para>
        
        <!-- Lets not document this now, cos we should migrate to use the printf format
        <para>
            You can use <literal>java.text.MessageFormat</literal> formatted strings:
        </para>
        
        <programlisting role="JAVA"><![CDATA[log.debug("The time is {0,time}", new Date());]]></programlisting>
        -->

        <para> 
            If <literal>User</literal> and <literal>Product</literal> are Seam components available in the current
            contexts, it gets even better: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Logger private Log log;
        
public Order createOrder(User user, Product product, int quantity) {
    log.debug("Creating new order for user: #{user.username} product: #{product.name} quantity: #0", quantity);
    return new Order(user, product, quantity);
}]]></programlisting>

        <para>
            Seam logging automagically chooses whether to send output to log4j or JDK logging. If log4j is in the
            classpath, Seam with use it. If it is not, Seam will use JDK logging.
        </para>

    </sect1>

    <sect1>
        <title>The <literal>Mutable</literal> interface and <literal>@ReadOnly</literal></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 is 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 role="JAVA"><![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> 
            Or, you can use the <literal>@ReadOnly</literal> annotation to achieve a similar effect: 
        </para>

        <programlisting role="JAVA"><![CDATA[@Name("account")
public class Account
{
    private BigDecimal balance;
    
    public void setBalance(BigDecimal balance)
    {
        this.balance = balance;
    }
    
    @ReadOnly
    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, <emphasis>unless the (conversation-scoped) 
            entity is currently associated with a Seam-managed persistence context, in which case no replication is 
            needed</emphasis>. This strategy is not necessarily 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 role="JAVA"><![CDATA[@Stateful
@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 Application Framework provides a great example 
            of managing an entity bean instance using a Seam component. 
        </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 to be able to inject
            them into our components using <literal>@In</literal> and use them in value and method binding expressions,
            etc. Sometimes, we even need to tie them into the Seam context lifecycle (<literal>@Destroy</literal>, for
            example). So the Seam contexts can contain objects which are not Seam components, and Seam provides a couple
            of nice features that make it easier to work with non-component objects bound to contexts. 
        </para>

        <para> 
            The <emphasis>factory component pattern</emphasis> lets a Seam component act as the instantiator for a
            non-component object. A <emphasis>factory method</emphasis> will be called when a context variable is
            referenced but has no value bound to it. We define factory methods using the <literal>@Factory</literal>
            annotation. The factory method binds a value to the context variable, and determines the scope of the bound
            value. There are two styles of factory method. The first style returns a value, which is bound to the
            context by Seam:
        </para>

        <programlisting role="JAVA"><![CDATA[@Factory(scope=CONVERSATION)
public List<Customer> getCustomerList() { 
    return ... ;
} ]]></programlisting>

        <para> 
            The second style is a method of type <literal>void</literal> which binds the value to the context
            variable itself: 
        </para>

        <programlisting role="JAVA"><![CDATA[@DataModel List<Customer> customerList;

@Factory("customerList")
public void initCustomerList() { 
    customerList = ...  ;
} ]]></programlisting>

        <para> 
            In both cases, the factory method is called when we reference the <literal>customerList</literal> context
            variable and its value is null, and then has no further part to play in the lifecycle of the value. An even
            more powerful pattern is the <emphasis>manager component pattern</emphasis>. In this case, we have a Seam
            component that is bound to a context variable, that manages the value of the context variable, while
            remaining invisible to clients. 
        </para>

        <para> 
            A manager component is any component with an <literal>@Unwrap</literal> method. This method returns the
            value that will be visable to clients, and is called <emphasis>every time</emphasis> a context variable is
            referenced. 
        </para>
        


        <programlisting role="JAVA"><![CDATA[@Name("customerList")
@Scope(CONVERSATION)
public class CustomerListManager
{
    ...
    
    @Unwrap
    public List<Customer> getCustomerList() { 
        return ... ;
    }
}]]></programlisting>

        <para> 
            The manager component pattern is especially useful if we have an object where you need more control over the 
            lifecycle of the component.  For example, if you have a heavyweight object that needs a cleanup operation when 
            the context ends you could <literal>@Unwrap</literal> the object, and perform cleanup in the 
            <literal>@Destroy</literal> method of the manager component.
        </para>
        
        <programlisting role="JAVA"><![CDATA[@Name("hens")
@Scope(APPLICATION) 
public class HenHouse {
    
    Set<Hen> hens;
    
    @In(required=false) Hen hen;
    
    @Unwrap
    public List<Hen> getHens() {
        if (hens == null) {
            // Setup our hens
        }
        return hens;
    }
    
    @Observer({"chickBorn", "chickenBoughtAtMarket"})
    public addHen() {
        hens.add(hen);
    }
    
    @Observer("chickenSoldAtMarket")
    public removeHen() {
        hens.remove(hen);
    }
    
    @Observer("foxGetsIn")
    public removeAllHens() {
        hens.clear();
    }
    ...
}]]> </programlisting>

	<para>
		Here the managed component observes many events which change the underlying object. 
		The component manages these actions itself, and because the object is unwrapped
		on every access, a consistent view is provided.
	</para>

    </sect1>

</chapter>
