[seam-commits] Seam SVN: r11654 - tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Mon Nov 23 19:33:32 EST 2009
Author: laubai
Date: 2009-11-23 19:33:31 -0500 (Mon, 23 Nov 2009)
New Revision: 11654
Modified:
tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Cache.xml
tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Tutorial.xml
Log:
Removed callout syntax, as it breaks in publican.
Modified: tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Cache.xml
===================================================================
--- tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Cache.xml 2009-11-24 00:07:11 UTC (rev 11653)
+++ tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Cache.xml 2009-11-24 00:33:31 UTC (rev 11654)
@@ -14,7 +14,7 @@
nodes of the cluster. What these silly people are really thinking of
is a "share nothing except for the database" architecture. Of course,
sharing the database is the primary problem with scaling a multi-user
- application—so the claim that this architecture is highly scalable
+ application — so the claim that this architecture is highly scalable
is absurd, and tells you a lot about the kind of applications that these
folks spend most of their time working on.
</para>
@@ -66,7 +66,7 @@
persistence context associated with a conversation-scoped stateful
session bean) acts as a cache of data that has been read in the
current conversation. This cache tends to have a pretty high
- hitrate! Seam optimizes the replication of Seam-managed persistence
+ hit rate! Seam optimizes the replication of Seam-managed persistence
contexts in a clustered environment, and there is no requirement for
transactional consistency with the database (optimistic locking is
sufficient) so you don't need to worry too much about the performance
Modified: tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Tutorial.xml
===================================================================
--- tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Tutorial.xml 2009-11-24 00:07:11 UTC (rev 11653)
+++ tags/JBPAPP_4_3_CP07_FP_CR1a/doc/Seam_Reference_Guide/en-US/Tutorial.xml 2009-11-24 00:33:31 UTC (rev 11654)
@@ -99,105 +99,107 @@
<emphasis>validation</emphasis> declaratively, via annotations. It also needs some extra
annotations that define the class as a Seam component. </para>
<!-- Can't use code hightlighting with callouts -->
- <example>
- <title></title>
- <programlisting role="JAVA">
- at Entity <co id="registration-entity-annotation"/>
+ <formalpara><title>User.java Example</title>
+ <para>
+<programlisting role="JAVA"><![CDATA[@Entity
@Name("user")
@Scope(SESSION)
@Table(name="users")
-public class User implements Serializable
-{
- private static final long serialVersionUID = 1881413500711441951L;
-
- private String username;
- private String password;
- private String name;
-
- public User(String name, String password, String username)
- {
- this.name = name;
- this.password = password;
- this.username = username;
- }
-
- public User() {}
-
- @NotNull @Length(min=5, max=15)
- public String getPassword()
- {
- return password;
- }
+public class User implements Serializable {
+ private static final long serialVersionUID = 1881413500711441951L;
+
+ private String username;
+ private String password;
+ private String name;
+
+ public User(String name, String password, String username) {
+ this.name = name;
+ this.password = password;
+ this.username = username;
+ }
+
+ public User() {}
+
+ @NotNull @Length(min=5, max=15)
+ public String getPassword() {
+ return password;
+ }
- public void setPassword(String password)
- {
- this.password = password;
- }
-
- @NotNull
- public String getName()
- {
- return name;
- }
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @NotNull
+ public String getName() {
+ return name;
+ }
- public void setName(String name)
- {
- this.name = name;
- }
-
- @Id @NotNull @Length(min=5, max=15)
- public String getUsername()
- {
- return username;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Id @NotNull @Length(min=5, max=15)
+ public String getUsername() {
+ return username;
+ }
- public void setUsername(String username)
- {
- this.username = username;
- }
+ public void setUsername(String username) {
+ this.username = username;
+ }
-}</programlisting>
-
- <para> The EJB3 standard <literal>@Entity</literal> annotation indicates that the
- <literal>User</literal> class is an entity bean. </para>
+}]]>
+</programlisting>
+ </para>
+ </formalpara>
- <para> A Seam component needs a <emphasis>component name</emphasis> specified by the
- <literal>@Name</literal>
- annotation. This name must be unique within the Seam application. When JSF
- asks Seam to resolve a context variable with a name that is the same as a Seam
- component name, and the context variable is currently undefined (null), Seam will
- instantiate that component, and bind the new instance to the context variable. In
- this case, Seam will instantiate a <literal>User</literal> the first time JSF
- encounters a variable named <literal>user</literal>. </para>
+<formalpara><title>User.java Explanatory Notes</title>
+<para>
- <para> Whenever Seam instantiates a component, it binds the new instance to a context
- variable in the component's <emphasis>default context</emphasis>. The default
- context is specified using the
- <literal>@Scope</literal>
- annotation. The <literal>User</literal> bean is a session scoped component.
- </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ The EJB3 standard <literal>@Entity</literal> annotation indicates that the <literal>User</literal> class is an entity bean.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A Seam component must have a <emphasis>component name</emphasis> specified by the <xref linkend="name-annotation" /> <literal>@Name</literal> annotation. This name must be unique within the Seam application. When JSF asks Seam to resolve a currently undefined (null) context variable whose name matches that of a Seam component, Seam will instantiate that component, and bind the new instance to the context variable. In this case, Seam will instantiate a <literal>User</literal> the first time JSF encounters a variable named <literal>user</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Whenever Seam instantiates a component, it binds the new instance to a context variable in the component's <emphasis>default context</emphasis>. The default context is specified using the <xref linkend="scope-annotation" /> <literal>@Scope</literal> annotation. The <literal>User</literal> bean is a session scoped component.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The EJB standard <literal>@Table</literal> annotation indicates that the <literal>User</literal> class is mapped to the <literal>users</literal> table.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>name</literal>, <literal>password</literal>, and <literal>username</literal> are the persistent attributes of the entity bean. All of our persistent attributes define accessor methods. These are needed when this component is used by JSF in the render response and update model values phases.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An empty constructor is required by both the EJB specification and by Seam.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>@NotNull</literal> and <literal>@Length</literal> annotations are part of the Hibernate Validator framework. Seam integrates Hibernate Validator and lets you use it for data validation (even if you are not using Hibernate for persistence).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The EJB standard <literal>@Id</literal> annotation indicates the primary key attribute of the entity bean.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+</formalpara>
- <para> The EJB standard <literal>@Table</literal> annotation indicates that the
- <literal>User</literal> class is mapped to the <literal>users</literal> table.
- </para>
-
- <para>
- <literal>name</literal>, <literal>password</literal> and <literal>username</literal>
- are the persistent attributes of the entity bean. All of our persistent attributes
- define accessor methods. These are needed when this component is used by JSF in the
- render response and update model values phases. </para>
-
- <para> An empty constructor is both required by both the EJB specification and by Seam.
- </para>
-
- <para> The <literal>@NotNull</literal> and <literal>@Length</literal> annotations are
- part of the Hibernate Validator framework. Seam integrates Hibernate Validator and
- lets you use it for data validation (even if you are not using Hibernate for
- persistence). </para>
-
- <para> The EJB standard <literal>@Id</literal> annotation indicates the primary key
- attribute of the entity bean. </para>
- </example>
<para> The most important things to notice in this example are the <literal>@Name</literal> and
<literal>@Scope</literal> annotations. These annotations establish that this class is a Seam component. </para>
<para> We'll see below that the properties of our <literal>User</literal> class are bound
@@ -221,92 +223,136 @@
<para> This is the only really interesting code in the example! </para>
<!-- Can't use code hightlighting with callouts -->
- <example>
- <title></title>
-
- <programlisting>
- at Stateless
+
+
+<formalpara><title>RegisterAction.java Example</title>
+ <para>
+
+
+<programlisting><![CDATA[@Stateless
@Name("register")
-public class RegisterAction implements Register
-{
+public class RegisterAction implements Register {
+ @In
+ private User user;
+
+ @PersistenceContext
+ private EntityManager em;
+
+ @Logger
+ private Log log;
+
+ public String register() {
+ List existing = em.createQuery(
+ "select username from User where username = #{user.username}")
+ .getResultList();
+
+ if (existing.size()==0) {
+ em.persist(user);
+ log.info("Registered new user #{user.username}");
+ return "/registered.xhtml";
+ } else {
+ FacesMessages.instance().add("User #{user.username} already exists");
+ return null;
+ }
+ }
- @In
- private User user;
-
- @PersistenceContext
- private EntityManager em;
-
- @Logger
- private Log log;
-
- public String register()
- {
- List existing = em.createQuery(
- "select username from User where username=#{user.username}")
- .getResultList();
-
- if (existing.size()==0)
- {
- em.persist(user);
- log.info("Registered new user #{user.username}");
- return "/registered.xhtml";
- }
- else
- {
- FacesMessages.instance().add("User #{user.username} already exists");
- return null;
- }
- }
-
-}</programlisting>
-
-
- <para> The EJB standard <literal>@Stateless</literal> annotation marks this class as
- a stateless session bean. </para>
-
- <para> The
- <literal>@In</literal>
- annotation marks an attribute of the bean as injected by Seam. In this case,
- the attribute is injected from a context variable named <literal>user</literal> (the
- instance variable name). </para>
-
- <para> The EJB standard <literal>@PersistenceContext</literal> annotation is used to
- inject the EJB3 entity manager. </para>
-
- <para> The Seam <literal>@Logger</literal> annotation is used to inject the component's
- <literal>Log</literal> instance. </para>
-
- <para> The action listener method uses the standard EJB3
- <literal>EntityManager</literal> API to interact with the database, and returns the
- JSF outcome. Note that, since this is a session bean, a transaction is automatically
- begun when the <literal>register()</literal> method is called, and committed when it
- completes. </para>
-
- <para> Notice that Seam lets you use a JSF EL expression inside EJB-QL. Under the
- covers, this results in an ordinary JPA <literal>setParameter()</literal> call on
- the standard JPA <literal>Query</literal> object. Nice, huh? </para>
-
- <para> The <literal>Log</literal> API lets us easily display templated log messages.
+}]]>
+</programlisting>
+ </para>
+ </formalpara>
+ <!-- </example> -->
+ <formalpara><title>RegisterAction.java Explanatory Notes</title>
+ <para>
+ <orderedlist>
+ <listitem>
+ <para>
+ The EJB <literal>@Stateless</literal> annotation marks this class as a stateless session bean.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <xref linkend="in-annotation" /> <literal>@In</literal> annotation marks an attribute of the bean as injected by Seam. In this case, the attribute is injected from a context variable named <literal>user</literal> (the instance variable name).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The EJB standard <literal>@PersistenceContext</literal> annotation is used to inject the EJB3 entity manager.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The Seam <literal>@Logger</literal> annotation is used to inject the component's <literal>Log</literal> instance.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The action listener method uses the standard EJB3 <literal>EntityManager</literal> API to interact with the database, and returns the JSF outcome. Note that, since this is a session bean, a transaction begins automatically when the <literal>register()</literal> method is called, and is committed when it completes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Notice that Seam lets you use a JSF EL expression inside EJB-QL. This results in an ordinary JPA <literal>setParameter()</literal> call on the standard JPA <literal>Query</literal> object.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>Log</literal> API allows easily display templated log messages that can include JSF EL expressions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ JSF action listener methods return a string-valued outcome that determines the next page displayed. A null outcome (or a void action listener method) redisplays the previous page. In plain JSF, it is normal to always use a JSF <emphasis>navigation rule</emphasis> to determine the JSF view ID from the outcome. For complex applications, this redirection is good practice. However, for very simple examples like this one, Seam lets you use the JSF view ID as the outcome, eliminating the need for a navigation rule.
+ </para>
+ <note>
+ <para>
+ When a view ID is used as an outcome, Seam always performs a browser redirect.
</para>
+ </note>
+ </listitem>
+ <listitem>
+ <para>
+ Seam provides a number of <emphasis>built-in components</emphasis> to help solve common problems. The <literal>FacesMessages</literal> component makes it easy to display templated error or success messages. (As of Seam 2.1, you can use <literal>StatusMessages</literal> instead, to remove the semantic dependency on JSF.) Built-in Seam components may be obtained by injection, or by calling the <literal>instance()</literal> method on the class of the built-in component.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </formalpara>
+ <!-- </example> -->
+ <para>
+ Note that we did not explicitly specify a <literal>@Scope</literal> this time. Each Seam component type has a default scope, which will be used if scope is not explicitly specified. For stateless session beans, the default scope is the stateless context.
+ </para>
+ <para>
+ The session bean action listener performs the business and persistence logic for our mini-application. In a more complex application, a separate service layer might be necessary, but Seam allows you to implement your own strategies for application layering. You can make any application as simple, or as complex, as you want.
+ </para>
+ <note>
+ <para>
+ This application is more complex than necessary for the sake of clear example code. All of the application code could have been eliminated by using Seam's application framework controllers.
+ </para>
+ </note>
+ </section>
+
+ <section>
+ <title>The session bean local interface: <literal>Register.java</literal></title>
+ <para>
+ The session bean requires a local interface.
+ </para>
+ <formalpara><title>Register.java Example</title>
+ <para>
+ <!-- <example>
+ <title>Register.java</title> -->
+
+<programlisting role="JAVA"><![CDATA[@Local
+public interface Register {
+ public String register();
+}]]></programlisting>
+ <!-- </example> -->
+ </para>
+ </formalpara>
+
+
+
+
- <para> JSF action listener methods return a string-valued outcome that determines what
- page will be displayed next. A null outcome (or a void action listener method)
- redisplays the previous page. In plain JSF, it is normal to always use a JSF
- <emphasis>navigation rule</emphasis> to determine the JSF view id from the
- outcome. For complex application this indirection is useful and a good practice.
- However, for very simple examples like this one, Seam lets you use the JSF view id
- as the outcome, eliminating the requirement for a navigation rule. <emphasis>Note
- that when you use a view id as an outcome, Seam always performs a browser
- redirect.</emphasis>
- </para>
-
- <para> Seam provides a number of <emphasis>built-in components</emphasis> to help solve
- common problems. The <literal>FacesMessages</literal> component makes it easy to
- display templated error or success messages. Built-in Seam components may be
- obtained by injection, or by calling an <literal>instance()</literal> method.
- </para>
- </example>
-
<para> Note that we did not explicitly specify a <literal>@Scope</literal> this time. Each Seam
component type has a default scope if not explicitly specified. For stateless session beans, the
default scope is the stateless context. Actually, <emphasis>all</emphasis> stateless session
@@ -775,89 +821,99 @@
<para> We want to cache the list of messages in memory between server requests, so we will make this a
stateful session bean. </para>
<!-- Can't use code hightlighting with callouts -->
- <example>
- <title></title>
- <programlisting>
- at Stateful
+
+<formalpara><title>MessageManagerBean.java Example</title>
+ <para>
+
+<programlisting><![CDATA[@Stateful
@Scope(SESSION)
@Name("messageManager")
-public class MessageManagerBean implements Serializable, MessageManager
-{
+public class MessageManagerBean implements Serializable, MessageManager {
+ @DataModel
+ private List<Message> messageList;
+
+ @DataModelSelection
+ @Out(required=false)
+ private Message message;
+
+ @PersistenceContext(type=EXTENDED)
+ private EntityManager em;
+
+ @Factory("messageList")
+ public void findMessages() {
+ messageList = em.createQuery("select msg from Message msg " +
+ "order by msg.datetime desc")
+ .getResultList();
+ }
+
+ public void select() {
+ message.setRead(true);
+ }
+
+ public void delete() {
+ messageList.remove(message);
+ em.remove(message);
+ message=null;
+ }
+
+ @Remove
+ public void destroy() {}
- @DataModel
- private List<Message> messageList;
-
- @DataModelSelection
- @Out(required=false)
- private Message message;
-
- @PersistenceContext(type=EXTENDED)
- private EntityManager em;
-
- @Factory("messageList")
- public void findMessages()
- {
- messageList = em.createQuery("from Message msg order by msg.datetime desc")
- .getResultList();
- }
-
- public void select()
- {
- message.setRead(true);
- }
-
- public void delete()
- {
- messageList.remove(message);
- em.remove(message);
- message=null;
- }
-
- @Remove
- public void destroy() {}
+}]]>
+</programlisting>
+ </para>
+ </formalpara>
+ <!-- </example> -->
+ <formalpara><title>MessageManagerBean.java Explanatory Notes</title>
+ <para>
+ <orderedlist>
+ <listitem>
+ <para>
+ The <literal>@DataModel</literal> annotation exposes an attibute of type <literal>java.util.List</literal> to the JSF page as an instance of <literal>javax.faces.model.DataModel</literal>. This allows us to use the list in a JSF <literal><![CDATA[<h:dataTable>]]></literal> with clickable links for each row. In this case, the <literal>DataModel</literal> is made available in a session context variable named <literal>messageList</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>@DataModelSelection</literal> annotation tells Seam to inject the <literal>List</literal> element corresponding to the clicked link.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>@Out</literal> annotation then exposes the selected value directly to the page. Every time a row of the clickable list is selected, the <literal>Message</literal> is injected to the attribute of the stateful bean, and subsequently "outjected" to the event context variable named <literal>message</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ This stateful bean has an EJB3 <emphasis>extended persistence context</emphasis>. This means that messages retrieved in the query remain in the managed state for as long as the bean exists. Any subsequent method calls to the stateful bean can therefore update the messages without needing to make an explicit call to the <literal>EntityManager</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The first time we navigate to the JSP page, the <literal>messageList</literal> context variable does not hold a value. The <literal>@Factory</literal> annotation tells Seam to create an instance of <literal>MessageManagerBean</literal> and invoke <literal>findMessages()</literal> — a factory method for messages — to initialize the value.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>select()</literal> action listener method marks the selected <literal>Message</literal> as read, and updates it in the database.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>delete()</literal> action listener method removes the selected <literal>Message</literal> from the database.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All stateful session bean Seam components <emphasis>must</emphasis> have a method <literal>@Remove</literal> defined, with no parameters marked. Seam uses this to remove the stateful bean and clean up any server-side state when the Seam context ends.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </formalpara>
-}</programlisting>
-
- <para> The <literal>@DataModel</literal> annotation exposes an attibute of type
- <literal>java.util.List</literal> to the JSF page as an instance of
- <literal>javax.faces.model.DataModel</literal>. This allows us to use the list
- in a JSF <literal><h:dataTable></literal> with clickable links for
- each row. In this case, the <literal>DataModel</literal> is made available in a
- session context variable named <literal>messageList</literal>. </para>
-
- <para> The <literal>@DataModelSelection</literal> annotation tells Seam to inject the
- <literal>List</literal> element that corresponded to the clicked link. </para>
-
- <para> The <literal>@Out</literal> annotation then exposes the selected value directly
- to the page. So every time a row of the clickable list is selected, the
- <literal>Message</literal> is injected to the attribute of the stateful bean,
- and the subsequently <emphasis>outjected</emphasis> to the event context variable
- named <literal>message</literal>. </para>
-
- <para> This stateful bean has an EJB3 <emphasis>extended persistence context</emphasis>.
- The messages retrieved in the query remain in the managed state as long as the bean
- exists, so any subsequent method calls to the stateful bean can update them without
- needing to make any explicit call to the <literal>EntityManager</literal>. </para>
-
- <para> The first time we navigate to the JSP page, there will be no value in the
- <literal>messageList</literal> context variable. The <literal>@Factory</literal>
- annotation tells Seam to create an instance of <literal>MessageManagerBean</literal>
- and invoke the <literal>findMessages()</literal> method to initialize the value. We
- call <literal>findMessages()</literal> a <emphasis>factory method</emphasis> for
- <literal>messages</literal>. </para>
-
- <para> The <literal>select()</literal> action listener method marks the selected
- <literal>Message</literal> as read, and updates it in the database. </para>
+
+
- <para> The <literal>delete()</literal> action listener method removes the selected
- <literal>Message</literal> from the database. </para>
-
- <para> All stateful session bean Seam components <emphasis>must</emphasis> have a method
- with no parameters marked <literal>@Remove</literal> that Seam uses to remove
- the stateful bean when the Seam context ends, and clean up any server-side state.
- </para>
- </example>
-
<para> Note that this is a session-scoped Seam component. It is associated with the user login session,
and all requests from a login session share the same instance of the component. (In Seam
applications, we usually use session-scoped components sparingly.) </para>
More information about the seam-commits
mailing list