You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2008/02/26 15:10:34 UTC
svn commit: r631219 [1/3] - /myfaces/orchestra/trunk/core/src/site/xdoc/
Author: skitching
Date: Tue Feb 26 06:10:33 2008
New Revision: 631219
URL: http://svn.apache.org/viewvc?rev=631219&view=rev
Log:
Tabs to spaces only
Modified:
myfaces/orchestra/trunk/core/src/site/xdoc/alternative-configuration.xml
myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml
myfaces/orchestra/trunk/core/src/site/xdoc/component-bindings.xml
myfaces/orchestra/trunk/core/src/site/xdoc/conversation.xml
myfaces/orchestra/trunk/core/src/site/xdoc/faqs.xml
myfaces/orchestra/trunk/core/src/site/xdoc/glossary.xml
myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml
myfaces/orchestra/trunk/core/src/site/xdoc/index.xml
myfaces/orchestra/trunk/core/src/site/xdoc/installation.xml
myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml
myfaces/orchestra/trunk/core/src/site/xdoc/persistence.xml
myfaces/orchestra/trunk/core/src/site/xdoc/todo.xml
myfaces/orchestra/trunk/core/src/site/xdoc/usage.xml
myfaces/orchestra/trunk/core/src/site/xdoc/viewController.xml
Modified: myfaces/orchestra/trunk/core/src/site/xdoc/alternative-configuration.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/alternative-configuration.xml?rev=631219&r1=631218&r2=631219&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/alternative-configuration.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/alternative-configuration.xml Tue Feb 26 06:10:33 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//Apache Software Foundation//DTD XDOC 1.0//EN"
- "http://www.apache.org/dtd/xdoc.dtd">
+ "http://www.apache.org/dtd/xdoc.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -21,34 +21,34 @@
-->
<document>
- <properties>
- <title>Apache MyFaces Orchestra - Alternative Configuration</title>
- </properties>
-
- <body>
- <section name="Installation">
- The following configuration provides a blueprint for
- a single Tomcat installation using Spring 2.0, jpa ri
- and runtime weaving.
-
- <subsection name="Prerequisites">
-
- <ul>
- <li>Prerequisites - Knowledge: Basic Spring 2.0 configuration knowledge, knowledge about
- the jpa ri, to the level that knowing what runtime weaving is can be assumed.
- </li>
- <li>Prerequisites - JDK Versions: JDK 5+ (on non Sun JDKs a working runtime weaving on 5
- or a 6+ non Sun JDK)</li>
- <li>Tomcat: 5.5+</li>
- <li>Spring 2.x+</li>
- </ul>
- </subsection>
- <subsection name="Spring configuration">
- The following configuration uses runtime weaving, and
- a connection pool. It should work on most Tomcat configurations.
-
-
- <pre>
+ <properties>
+ <title>Apache MyFaces Orchestra - Alternative Configuration</title>
+ </properties>
+
+ <body>
+ <section name="Installation">
+ The following configuration provides a blueprint for
+ a single Tomcat installation using Spring 2.0, jpa ri
+ and runtime weaving.
+
+ <subsection name="Prerequisites">
+
+ <ul>
+ <li>Prerequisites - Knowledge: Basic Spring 2.0 configuration knowledge, knowledge about
+ the jpa ri, to the level that knowing what runtime weaving is can be assumed.
+ </li>
+ <li>Prerequisites - JDK Versions: JDK 5+ (on non Sun JDKs a working runtime weaving on 5
+ or a 6+ non Sun JDK)</li>
+ <li>Tomcat: 5.5+</li>
+ <li>Spring 2.x+</li>
+ </ul>
+ </subsection>
+ <subsection name="Spring configuration">
+ The following configuration uses runtime weaving, and
+ a connection pool. It should work on most Tomcat configurations.
+
+
+ <pre>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -57,14 +57,14 @@
xmlns:sa="https://spring-annotation.dev.java.net/context"
xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
- >
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
+ >
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
-
+
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
@@ -85,10 +85,10 @@
<property name="driverClassName" value="org.h2.Driver" />
<property name="url"
value="jdbc:h2:/DATA/dummydatabase;MODE=MYSQL" />
-
+
<property name="username" value="theusername" />
<property name="password" value="thepassword" />
-
+
<property name="initialSize">
<value>2</value>
</property>
@@ -106,7 +106,7 @@
<property name="dataSource" ref="thedataSource" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
- </property>
+ </property>
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
@@ -115,9 +115,9 @@
<property name="databasePlatform" value="oracle.toplink.essentials.platform.database.MySQL4Platform" />
</bean>
</property>
-
+
<property name="jpaProperties">
-
+
<props>
<prop key="toplink.logging.level">INFO</prop>
<prop key="toplink.target-database">oracle.toplink.essentials.platform.database.MySQL4Platform</prop>
@@ -125,7 +125,7 @@
<prop key="toplink.cache.type.default">HardWeak</prop>
<prop key="toplink.cache.size.default">5000</prop>
</props>
- </property>
+ </property>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
@@ -136,7 +136,7 @@
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
-
+
</bean>
<bean id="jpaPersistentContextFactory" class="org.apache.myfaces.orchestra.conversation.persistenceContexts.JpaPersistenceContextFactory">
@@ -146,31 +146,31 @@
<property name="persistenceContextFactory" ref="jpaPersistentContextFactory" />
</bean>
- </beans>
- </pre>
-
- This configuration enables load time weaving of the orm classes and thus allows
- lazy instantiation of classes. The main issue with this configuration is, that
- Tomcat still needs a javaagent passed down as parameter. If this is not done
- the loadtime weaving ultimately will fail.
- the required javaagent is:
- <pre>
+ </beans>
+ </pre>
+
+ This configuration enables load time weaving of the orm classes and thus allows
+ lazy instantiation of classes. The main issue with this configuration is, that
+ Tomcat still needs a javaagent passed down as parameter. If this is not done
+ the loadtime weaving ultimately will fail.
+ the required javaagent is:
+ <pre>
-javaagent:<path to the spring weavers>/weavers/spring-agent.jar
- </pre>
- There are weaverless configurations as well, in spring 2.0.2 it was not yet possible to enable
- them for jpa and Tomcat. This situation might change soon, please refer to the Spring documentation
- for additional information on how to enable the loadtime weaving of jpa classes.
-
- </subsection>
- <subsection name="Key differences to the original configuration">
- Following key differences can be found:
- <ul>
- <li> Load time weaving enabled via: <property name="loadTimeWeaver"> </li>
- <li> A connection pool was used instead of a plain jdbc connection </li>
- <li> Tomcat has to be started with an appropriate javaagent statement </li>
- </ul>
- </subsection>
-
- </section>
- </body>
-</document>
+ </pre>
+ There are weaverless configurations as well, in spring 2.0.2 it was not yet possible to enable
+ them for jpa and Tomcat. This situation might change soon, please refer to the Spring documentation
+ for additional information on how to enable the loadtime weaving of jpa classes.
+
+ </subsection>
+ <subsection name="Key differences to the original configuration">
+ Following key differences can be found:
+ <ul>
+ <li> Load time weaving enabled via: <property name="loadTimeWeaver"> </li>
+ <li> A connection pool was used instead of a plain jdbc connection </li>
+ <li> Tomcat has to be started with an appropriate javaagent statement </li>
+ </ul>
+ </subsection>
+
+ </section>
+ </body>
+</document>
Modified: myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml?rev=631219&r1=631218&r2=631219&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml Tue Feb 26 06:10:33 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//Apache Software Foundation//DTD XDOC 1.0//EN"
- "http://www.apache.org/dtd/xdoc.dtd">
+ "http://www.apache.org/dtd/xdoc.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -19,209 +19,209 @@
specific language governing permissions and limitations
under the License.
-->
- <document>
- <properties>
- <title>Apache MyFaces Orchestra - Best Practice</title>
- </properties>
-
- <body>
- <section name="Best Practice">
-
- This page contains information on how the Orchestra developers believe Orchestra
- is best used. As always, best practices evolve - see the wiki for the latest
- information.
-
- <subsection name="Single Page Conversation With Access Scope">
-
- <p>
- This applies when you have a single page that the user may submit multiple times
- (eg select an item from a list and click a button, then select a different item
- and click another button). The state of the page changes after each submit, but
- this state must be held in memory.
- </p>
-
- <p>
- Write a single managed bean for the view. Configure this bean as belonging
- to an unnamed access-scoped conversation and reference it as normal from
- your presentation pages (jsp, facelets, clay, etc).
- </p>
-
- <p>
- The conversation will be started when the bean is first accessed, and will
- automatically be terminated (ie the bean will be deleted) when navigation
- to some other page occurs (well, technically when a page is rendered that
- does not reference this managed bean). If you have an action method that wants
- to "start fresh" while remaining at the same view, then from the action method call
- ConversationUtils.invalidateAndRestartCurrent() to discard the current
- conversation.
- </p>
-
- <p>
- If this bean is named to match the view that it is backing
- (eg beanname="edit" for the "/edit" viewid), then it is trivial
- to get "lifecycle events" from Orchestra's ViewController. Even if
- the bean-name does not match the view, there are ways of configuring
- things so it still receives the appropriate callbacks. See the
- ViewController documentation for more information on this.
- </p>
-
- </subsection>
-
- <subsection name="Multi Page Conversation With Access Scope">
- <p>
- This applies when you have a set of pages that cooperate together to interact
- with the user, but where the state used by these pages must be held in memory.
- Commonly, sequences of pages like this eventually lead to a "save" or "execute"
- button which then performs an action using the state that was set up by the user
- via the preceding pages. Such sequences are sometimes called a "wizard".
- </p>
-
- <p>
- Use one access-scoped controller for the whole conversation, plus one simple
- request-scoped or access-scoped bean per view. For example, if you have three
- pages then structure things as follows:
-
- <ul>
- <li>Page:purchaseStep1.jsp<br/>Bean name: purchaseStep1</li>
- <li>Page:purchaseStep2.jsp<br/>Bean name: purchaseStep2</li>
- <li>Page:purchaseStep3.jsp<br/>Bean name: purchaseStep3</li>
- <li>Conversation bean name: purchaseController</li>
- </ul>
- </p>
-
- <p>
- Generally, there is no need to specify a conversationName attribute for these beans,
- ie the name of the conversation they are in is the same as the name of the bean.
- </p>
- <p>
- The per-view beans handle logic and state that is specific to that page. If there is state needed
- for the page, then use "access" scope, otherwise use "request" scope. Inject the controller bean
- into each per-view bean so that state and logic which is shared between views can be accessed.
- </p>
- <p>
- If there is common logic that each page shares, then that can be defined in an abstract base bean
- which the per-view beans extend.
- </p>
- <p>
- EL expressions in the pages can reference either the per-view bean or the common controller bean,
- whichever is appropriate.
- </p>
- <p>
- There are two problems with workflows:
- <ul>
- <li>
- <p>
- A conversation may timeout in the middle of a conversation
- (eg the user goes to lunch, then tries to continue on return), and
- </p>
- </li>
- <li>
- <p>
- A user may try to leap into the middle of a conversation (eg via a bookmark)
- </p>
- </li>
- </ul>
- With the above recommended structure, each per-view bean except the first one can then
- check whether the conversation exists and is in an appropriate state for that view.
- If not, then a navigation to the proper "entry page" for the conversation can be done.
- </p>
- <p>
- The basic check for the existence of the conversation is fairly simple to do in java code:
- <pre>
+ <document>
+ <properties>
+ <title>Apache MyFaces Orchestra - Best Practice</title>
+ </properties>
+
+ <body>
+ <section name="Best Practice">
+
+ This page contains information on how the Orchestra developers believe Orchestra
+ is best used. As always, best practices evolve - see the wiki for the latest
+ information.
+
+ <subsection name="Single Page Conversation With Access Scope">
+
+ <p>
+ This applies when you have a single page that the user may submit multiple times
+ (eg select an item from a list and click a button, then select a different item
+ and click another button). The state of the page changes after each submit, but
+ this state must be held in memory.
+ </p>
+
+ <p>
+ Write a single managed bean for the view. Configure this bean as belonging
+ to an unnamed access-scoped conversation and reference it as normal from
+ your presentation pages (jsp, facelets, clay, etc).
+ </p>
+
+ <p>
+ The conversation will be started when the bean is first accessed, and will
+ automatically be terminated (ie the bean will be deleted) when navigation
+ to some other page occurs (well, technically when a page is rendered that
+ does not reference this managed bean). If you have an action method that wants
+ to "start fresh" while remaining at the same view, then from the action method call
+ ConversationUtils.invalidateAndRestartCurrent() to discard the current
+ conversation.
+ </p>
+
+ <p>
+ If this bean is named to match the view that it is backing
+ (eg beanname="edit" for the "/edit" viewid), then it is trivial
+ to get "lifecycle events" from Orchestra's ViewController. Even if
+ the bean-name does not match the view, there are ways of configuring
+ things so it still receives the appropriate callbacks. See the
+ ViewController documentation for more information on this.
+ </p>
+
+ </subsection>
+
+ <subsection name="Multi Page Conversation With Access Scope">
+ <p>
+ This applies when you have a set of pages that cooperate together to interact
+ with the user, but where the state used by these pages must be held in memory.
+ Commonly, sequences of pages like this eventually lead to a "save" or "execute"
+ button which then performs an action using the state that was set up by the user
+ via the preceding pages. Such sequences are sometimes called a "wizard".
+ </p>
+
+ <p>
+ Use one access-scoped controller for the whole conversation, plus one simple
+ request-scoped or access-scoped bean per view. For example, if you have three
+ pages then structure things as follows:
+
+ <ul>
+ <li>Page:purchaseStep1.jsp<br/>Bean name: purchaseStep1</li>
+ <li>Page:purchaseStep2.jsp<br/>Bean name: purchaseStep2</li>
+ <li>Page:purchaseStep3.jsp<br/>Bean name: purchaseStep3</li>
+ <li>Conversation bean name: purchaseController</li>
+ </ul>
+ </p>
+
+ <p>
+ Generally, there is no need to specify a conversationName attribute for these beans,
+ ie the name of the conversation they are in is the same as the name of the bean.
+ </p>
+ <p>
+ The per-view beans handle logic and state that is specific to that page. If there is state needed
+ for the page, then use "access" scope, otherwise use "request" scope. Inject the controller bean
+ into each per-view bean so that state and logic which is shared between views can be accessed.
+ </p>
+ <p>
+ If there is common logic that each page shares, then that can be defined in an abstract base bean
+ which the per-view beans extend.
+ </p>
+ <p>
+ EL expressions in the pages can reference either the per-view bean or the common controller bean,
+ whichever is appropriate.
+ </p>
+ <p>
+ There are two problems with workflows:
+ <ul>
+ <li>
+ <p>
+ A conversation may timeout in the middle of a conversation
+ (eg the user goes to lunch, then tries to continue on return), and
+ </p>
+ </li>
+ <li>
+ <p>
+ A user may try to leap into the middle of a conversation (eg via a bookmark)
+ </p>
+ </li>
+ </ul>
+ With the above recommended structure, each per-view bean except the first one can then
+ check whether the conversation exists and is in an appropriate state for that view.
+ If not, then a navigation to the proper "entry page" for the conversation can be done.
+ </p>
+ <p>
+ The basic check for the existence of the conversation is fairly simple to do in java code:
+ <pre>
public void initView()
{
ConversationUtils.ensureConversationRedirect("purchaseController", "/purchaseStep1.jsf");
}
- </pre>
- If a set of per-view beans share a common base class then this initView method can be
- added to the base class, then overridden only in the page that is redirected to
- ("purchaseStep1.jsp" in this example) to prevent circular redirects. This then protects
- all of the pages from access without a correctly initialised conversation.
- </p>
-
- <p>
- There is one issue: after redirect it would sometimes be nice to display an error
- message indicating *why* the redirect happened, eg "Invalid Conversation State". This
- is not easy on a redirect. A forward would be easier to handle, as that data could
- be placed in request scope.
- </p>
- <p>
- Without this check, when a user leaps into the middle of a conversation, EL expressions
- will trigger the creation of the missing purchaseController (and its associated conversation)
- but the bean probably does not have the appropriate state to render the page correctly.
- </p>
-
- <p>
- The orchestra core15 module provides the @ConversationRequire annotation to make this even easier.
- </p>
-
- <p>
- Note that this works even when the purchaseController bean (which is in the purchaseController
- conversation, unless otherwise configured) is injected into the per-view bean. The object
- injected is actually a proxy, so the conversation is not created until the bean is really
- referenced.
- </p>
-
- <p>
- <b>Notice:</b> There is also a <code>JsfConversationUtils</code>-class which allows
- you to invoke a navigation rule rather than encoding a url in the call to
- method ensureConversationRedirect.
- </p>
-
- <p>
- If the views in a workflow are so simple that there is no logic or state needed, then
- rather than declaring "dummy beans" just to receive lifecycle callbacks the way the
- ViewController maps viewids to beannames can be configured. In particular, see the
- ViewController annotations from the Orchestra core15 module. Having a separate bean
- for the "entry page" of a workflow is always a good idea however.
- </p>
-
- </subsection>
-
- <subsection name="Multi Page Conversation With Manual Scope">
-
- <p>
- In some cases a conversation should not terminate until page N has been visited,
- but in the middle a user can go off and visit a page that has no references to
- any managed beans within the main conversation. When using Access scopes, Orchestra
- will interpret a visit to such as page as the user "abandoning" the conversation,
- so the conversation will be discarded. In this case, use a manual scoped conversation,
- ie one that must be explicitly ended via either a JSF component (ox:endConversation)
- or a call to the Orchestra API from an action method. Use access scopes where possible,
- though - they are less work.
- </p>
-
- </subsection>
-
- <subsection name="Avoid Session Scope">
- <p>
- In almost all cases, using Session scope is a bad idea. All sorts of data goes into
- sessions, including data from UI frameworks, and sometimes from the servlet engine
- itself. Instead of using session-scope, put all such beans into a single conversation
- scope called "session". The most significant benefit from this is that Orchestra's
- "conversation context" feature now allows a user to open multiple windows to your
- app without problems; each window has a different "conversation context", and each
- "conversation context" has a completely independent set of conversations - including
- all the beans in the "session" conversation. It's almost like the user connecting
- from two different machines - except that any application login (authentication)
- data is shared.
- </p>
- <p>
- There are a few places where real session-scoped data might be appropriate, but not
- many. Think whether two separate browser windows for a user really should share that
- data. And if they should, then make sure that the shared objects are thread-safe, as
- two concurrent requests from two different windows will be using the same instance.
- </p>
- </subsection>
-
- <subsection name="Component bindings">
- <p>
- We recommend you read about <a href="component-bindings.html">component binding and the scoping problem</a>.
- This document is not specifically about Apache MyFaces Orchestra, but the same issues apply when dealing
- with component-bindings and conversation-scoped beans.
- </p>
- </subsection>
+ </pre>
+ If a set of per-view beans share a common base class then this initView method can be
+ added to the base class, then overridden only in the page that is redirected to
+ ("purchaseStep1.jsp" in this example) to prevent circular redirects. This then protects
+ all of the pages from access without a correctly initialised conversation.
+ </p>
+
+ <p>
+ There is one issue: after redirect it would sometimes be nice to display an error
+ message indicating *why* the redirect happened, eg "Invalid Conversation State". This
+ is not easy on a redirect. A forward would be easier to handle, as that data could
+ be placed in request scope.
+ </p>
+ <p>
+ Without this check, when a user leaps into the middle of a conversation, EL expressions
+ will trigger the creation of the missing purchaseController (and its associated conversation)
+ but the bean probably does not have the appropriate state to render the page correctly.
+ </p>
+
+ <p>
+ The orchestra core15 module provides the @ConversationRequire annotation to make this even easier.
+ </p>
+
+ <p>
+ Note that this works even when the purchaseController bean (which is in the purchaseController
+ conversation, unless otherwise configured) is injected into the per-view bean. The object
+ injected is actually a proxy, so the conversation is not created until the bean is really
+ referenced.
+ </p>
+
+ <p>
+ <b>Notice:</b> There is also a <code>JsfConversationUtils</code>-class which allows
+ you to invoke a navigation rule rather than encoding a url in the call to
+ method ensureConversationRedirect.
+ </p>
+
+ <p>
+ If the views in a workflow are so simple that there is no logic or state needed, then
+ rather than declaring "dummy beans" just to receive lifecycle callbacks the way the
+ ViewController maps viewids to beannames can be configured. In particular, see the
+ ViewController annotations from the Orchestra core15 module. Having a separate bean
+ for the "entry page" of a workflow is always a good idea however.
+ </p>
+
+ </subsection>
+
+ <subsection name="Multi Page Conversation With Manual Scope">
+
+ <p>
+ In some cases a conversation should not terminate until page N has been visited,
+ but in the middle a user can go off and visit a page that has no references to
+ any managed beans within the main conversation. When using Access scopes, Orchestra
+ will interpret a visit to such as page as the user "abandoning" the conversation,
+ so the conversation will be discarded. In this case, use a manual scoped conversation,
+ ie one that must be explicitly ended via either a JSF component (ox:endConversation)
+ or a call to the Orchestra API from an action method. Use access scopes where possible,
+ though - they are less work.
+ </p>
+
+ </subsection>
+
+ <subsection name="Avoid Session Scope">
+ <p>
+ In almost all cases, using Session scope is a bad idea. All sorts of data goes into
+ sessions, including data from UI frameworks, and sometimes from the servlet engine
+ itself. Instead of using session-scope, put all such beans into a single conversation
+ scope called "session". The most significant benefit from this is that Orchestra's
+ "conversation context" feature now allows a user to open multiple windows to your
+ app without problems; each window has a different "conversation context", and each
+ "conversation context" has a completely independent set of conversations - including
+ all the beans in the "session" conversation. It's almost like the user connecting
+ from two different machines - except that any application login (authentication)
+ data is shared.
+ </p>
+ <p>
+ There are a few places where real session-scoped data might be appropriate, but not
+ many. Think whether two separate browser windows for a user really should share that
+ data. And if they should, then make sure that the shared objects are thread-safe, as
+ two concurrent requests from two different windows will be using the same instance.
+ </p>
+ </subsection>
+
+ <subsection name="Component bindings">
+ <p>
+ We recommend you read about <a href="component-bindings.html">component binding and the scoping problem</a>.
+ This document is not specifically about Apache MyFaces Orchestra, but the same issues apply when dealing
+ with component-bindings and conversation-scoped beans.
+ </p>
+ </subsection>
- </section>
- </body>
+ </section>
+ </body>
</document>
Modified: myfaces/orchestra/trunk/core/src/site/xdoc/component-bindings.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/component-bindings.xml?rev=631219&r1=631218&r2=631219&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/component-bindings.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/component-bindings.xml Tue Feb 26 06:10:33 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//Apache Software Foundation//DTD XDOC 1.0//EN"
- "http://www.apache.org/dtd/xdoc.dtd">
+ "http://www.apache.org/dtd/xdoc.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -21,130 +21,130 @@
-->
<document>
- <properties>
- <title>Apache MyFaces Orchestra - Component Bindings</title>
- </properties>
+ <properties>
+ <title>Apache MyFaces Orchestra - Component Bindings</title>
+ </properties>
- <body>
- <section name="Component Bindings">
- <subsection name="Introduction">
- <subsubsection name="Basic discrepancy">
- <p>
- JSF components interact with backing beans. However the lifecycles of these two types of
- objects are very different; beans may last just a request, or longer (eg a session bean).
- A component logically may last a number of page views, but physically new instances are
- created for each request, when the view is "restored".
- </p>
- <p>
- JSF is designed so that in normal cases views "pull" data from backing beans, "push" data entered by the
- user into backing beans, and "invoke" event-handler methods on backing beans. In all cases, the dependency
- is unidirectional: views know about beans, but beans do not know about views. And the coupling is done
- only via EL strings, not hard references. This means that the lifecycles of the view components and
- the backing beans they reference are decoupled, and the lifecycle mismatch is not an issue.
- </p>
- <p>
- However JSF does provide a mechanism for backing beans to access view components in the rare cases where
- this is necessary: "bindings". Unfortunately the coupling here is done via direct object references, not
- EL strings. And if a bean then holds on to these references then very bad things can happen if the
- lifetime of the bean is longer than a request. Just one of the possible problems is the ugly
- "duplicate component id" error.
- </p>
- <p>
- Note that "bindings" are not generally a good idea, and should be avoided where possible. In the
- remainder of this page we assume that you have some very good reason for wanting bindings, and
- show you how they can be used with non-request-scoped beans.
- </p>
+ <body>
+ <section name="Component Bindings">
+ <subsection name="Introduction">
+ <subsubsection name="Basic discrepancy">
+ <p>
+ JSF components interact with backing beans. However the lifecycles of these two types of
+ objects are very different; beans may last just a request, or longer (eg a session bean).
+ A component logically may last a number of page views, but physically new instances are
+ created for each request, when the view is "restored".
+ </p>
+ <p>
+ JSF is designed so that in normal cases views "pull" data from backing beans, "push" data entered by the
+ user into backing beans, and "invoke" event-handler methods on backing beans. In all cases, the dependency
+ is unidirectional: views know about beans, but beans do not know about views. And the coupling is done
+ only via EL strings, not hard references. This means that the lifecycles of the view components and
+ the backing beans they reference are decoupled, and the lifecycle mismatch is not an issue.
+ </p>
+ <p>
+ However JSF does provide a mechanism for backing beans to access view components in the rare cases where
+ this is necessary: "bindings". Unfortunately the coupling here is done via direct object references, not
+ EL strings. And if a bean then holds on to these references then very bad things can happen if the
+ lifetime of the bean is longer than a request. Just one of the possible problems is the ugly
+ "duplicate component id" error.
+ </p>
+ <p>
+ Note that "bindings" are not generally a good idea, and should be avoided where possible. In the
+ remainder of this page we assume that you have some very good reason for wanting bindings, and
+ show you how they can be used with non-request-scoped beans.
+ </p>
</subsubsection>
-
- </subsection>
- <subsection name="Problem">
- <p>
- In order to avoid the lifecycle mismatch between components and beans, any bean that stores a component
- binding must be request-scoped.
- </p>
- <p>
- However what has been recommended in the "Orchestra best practices" is an access-scoped backing bean for
- a view and an additional (access or manual) conversation-scoped controller for multi-page conversations.
- The page controller/model now is stateful, which is exactly what we wanted, however when component bindings
- are needed then they should not be stored on these beans because they are not request-scoped.
- </p>
- <p>
- Therefore the following construct is bound to fail:
- <pre>
-<component binding="#{viewcontrollerbean.bindingattribute}" />
- </pre>
- due to the difference in scopes.
- </p>
- <p>
+
+ </subsection>
+ <subsection name="Problem">
+ <p>
+ In order to avoid the lifecycle mismatch between components and beans, any bean that stores a component
+ binding must be request-scoped.
+ </p>
+ <p>
+ However what has been recommended in the "Orchestra best practices" is an access-scoped backing bean for
+ a view and an additional (access or manual) conversation-scoped controller for multi-page conversations.
+ The page controller/model now is stateful, which is exactly what we wanted, however when component bindings
+ are needed then they should not be stored on these beans because they are not request-scoped.
+ </p>
+ <p>
+ Therefore the following construct is bound to fail:
+ <pre>
+<component binding="#{viewcontrollerbean.bindingattribute}" />
+ </pre>
+ due to the difference in scopes.
+ </p>
+ <p>
There are two possible solutions to this problem.
- </p>
- </subsection>
+ </p>
+ </subsection>
- <subsection name="Solution 1: Spring aop-proxy">
- <p>
- Spring in 2.0 has introduced a construct called aop-proxy. This is a special tag which can be embedded
- into beans which basically does nothing more than to weave a proxy object around an existing object which inherits
- the scope of the referencing bean.
- The inner part of the proxy or own bean then can have a scope of its own which can be smaller than the scope
- of the referencing object.
- </p>
- <p>
- So how does this help? Lets look again at our example
- <pre>
-<component binding="#{viewcontrollerbean.componentbindingmodel.bindingattribute}" />
- </pre>
- </p>
- <p>
- The accessor path has slightly changed, we have introduced a second bean; a model
- bean which specifically holds our component bindings.
- </p>
- <p>
- What happens on the spring configuration side is simply the following:
- <pre>
+ <subsection name="Solution 1: Spring aop-proxy">
+ <p>
+ Spring in 2.0 has introduced a construct called aop-proxy. This is a special tag which can be embedded
+ into beans which basically does nothing more than to weave a proxy object around an existing object which inherits
+ the scope of the referencing bean.
+ The inner part of the proxy or own bean then can have a scope of its own which can be smaller than the scope
+ of the referencing object.
+ </p>
+ <p>
+ So how does this help? Lets look again at our example
+ <pre>
+<component binding="#{viewcontrollerbean.componentbindingmodel.bindingattribute}" />
+ </pre>
+ </p>
+ <p>
+ The accessor path has slightly changed, we have introduced a second bean; a model
+ bean which specifically holds our component bindings.
+ </p>
+ <p>
+ What happens on the spring configuration side is simply the following:
+ <pre>
<bean id="componentbindingmodel" scope="request" class="path.to.our.model.class"/>
<bean id="viewcontrollerbean" scope="conversation.access" ...>
<property name="componentbindingmodel"
ref="componentbindingmodel" />
</bean>
- </pre>
- </p>
- <p>
- The associated component binding model class is a class which only holds the components as attributes and
- provides associated setter and getter methods. The viewcontrollerbean class can then invoke its
- methods to get access to the bound component instances.
- </p>
- <p>
- When the viewcontrollerbean object is instantiated, Spring sees that it must inject the bean named
- "componentbindingmodel" into it. However that bean is marked as an aop:proxy, so what spring injects
- is just a "proxy" object, not a real componentbindingmodel bean. Whenever the viewcontrollerbean
- then invokes a method on that proxy object, the proxy looks up bean "componentbindingmodel" in
- the specified scope (request), then invokes that method on the object it found. This does have a
- significant performance impact; each method call on the proxy performs the bean lookup again.
- However it always acts on the "latest" version of that bean, which would not happen if a real
- reference had been held. At the end of the request, the request-scoped componentbindingmodel object
- is discarded as normal, and only the proxy "shell" remains. At the next request, a new componentbindingmodel
- instance is created and added into the request scope, and methods invoked on the proxy will then
- automatically work against this new object.
- </p>
- </subsection>
- <subsection name="Solution 2: A request-scoped facade">
- <p>
- Only a few of the methods on the non-request-scoped backing bean will need access to the bound
- components. Therefore, these methods can be moved into a request-scoped bean. Add the component
- binding methods to this request-scoped bean too, and inject a reference to the "real" backing
- bean into it. Alter the view so that EL expressions that need those component bindings to
- be evaluated point to the request-scoped bean.
- </p>
- <p>
- Another way of thinking about this is that the "real" backing bean for the page is implemented as
- request-scoped, and any state it needs to retain is pushed into a "helper" object that is of
- conversation scope. The request-scoped bean has access to the components without problems.
- </p>
- <p>
- While either of these solutions means yet another backing-bean class for the view, there is no
- "spring magic" required.
- </p>
- </subsection>
- </section>
- </body>
+ </pre>
+ </p>
+ <p>
+ The associated component binding model class is a class which only holds the components as attributes and
+ provides associated setter and getter methods. The viewcontrollerbean class can then invoke its
+ methods to get access to the bound component instances.
+ </p>
+ <p>
+ When the viewcontrollerbean object is instantiated, Spring sees that it must inject the bean named
+ "componentbindingmodel" into it. However that bean is marked as an aop:proxy, so what spring injects
+ is just a "proxy" object, not a real componentbindingmodel bean. Whenever the viewcontrollerbean
+ then invokes a method on that proxy object, the proxy looks up bean "componentbindingmodel" in
+ the specified scope (request), then invokes that method on the object it found. This does have a
+ significant performance impact; each method call on the proxy performs the bean lookup again.
+ However it always acts on the "latest" version of that bean, which would not happen if a real
+ reference had been held. At the end of the request, the request-scoped componentbindingmodel object
+ is discarded as normal, and only the proxy "shell" remains. At the next request, a new componentbindingmodel
+ instance is created and added into the request scope, and methods invoked on the proxy will then
+ automatically work against this new object.
+ </p>
+ </subsection>
+ <subsection name="Solution 2: A request-scoped facade">
+ <p>
+ Only a few of the methods on the non-request-scoped backing bean will need access to the bound
+ components. Therefore, these methods can be moved into a request-scoped bean. Add the component
+ binding methods to this request-scoped bean too, and inject a reference to the "real" backing
+ bean into it. Alter the view so that EL expressions that need those component bindings to
+ be evaluated point to the request-scoped bean.
+ </p>
+ <p>
+ Another way of thinking about this is that the "real" backing bean for the page is implemented as
+ request-scoped, and any state it needs to retain is pushed into a "helper" object that is of
+ conversation scope. The request-scoped bean has access to the components without problems.
+ </p>
+ <p>
+ While either of these solutions means yet another backing-bean class for the view, there is no
+ "spring magic" required.
+ </p>
+ </subsection>
+ </section>
+ </body>
</document>
Modified: myfaces/orchestra/trunk/core/src/site/xdoc/conversation.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/conversation.xml?rev=631219&r1=631218&r2=631219&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/conversation.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/conversation.xml Tue Feb 26 06:10:33 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//Apache Software Foundation//DTD XDOC 1.0//EN"
- "http://www.apache.org/dtd/xdoc.dtd">
+ "http://www.apache.org/dtd/xdoc.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -21,156 +21,156 @@
-->
<document>
- <properties>
- <title>Apache MyFaces Orchestra - The Conversation Scope Problem</title>
- </properties>
-
- <body>
- <section name="The Conversation Scope Problem">
- <p>
- Often a logical operation consists of multiple JSF requests to the server.
- For example, purchasing an insurance policy requires completing a number
- of related forms (often referred to as a "conversation", "workflow" or
- "dialog"), during which the same java objects need to be kept in memory.
- </p>
-
- <p>
- However JSF provides only three scopes for data to be stored in:
- <ul>
- <li><p>Application scope</p></li>
- <li><p>Session scope</p></li>
- <li><p>Request scope</p></li>
- </ul>
- </p>
-
- <p>
- Application scope is only rarely of use; such data is shared across all users of that JSF application.
- Request scope is not useful for the above scenario; all data stored in request scope is discarded at
- the end of each "command".
- </p>
-
- <p>
- Session scope can be used to hold data across multiple requests (a conversation),
- but suffers from a number of other issues:
- <ul>
- <li><p>When the conversation is complete, it is best to discard all the related objects in order
- to save memory. However this is quite difficult to do when using session scope.</p></li>
- <li><p>When a user performs some task for a second time (eg purchasing a second insurance policy),
- it is usually better for the backing beans to be new instances rather than having whatever
- state they had at the end of the previous pass. This is difficult to achieve when the beans
- are in session scope; every relevant bean needs to be explicitly deleted or reset. However
- when these objects are stored in a conversation this happens automatically as the conversation
- (with all its beans) has been discarded.</p></li>
- <li><p>The user cannot have multiple windows open on the same site. Sessions are typically
- tracked using cookies, and all windows associated with the same browser instance
- share cookies and therefore are within the same "session". If two windows are created
- for the same session then very strange effects can be caused due to the same "backing beans"
- being used by the two windows. Note that JSF implementations generally provide support for
- multiple concurrent windows (eg MyFaces and Sun RI) but this only means that the JSF
- *components* are safe for use with multiple windows; any application that uses only
- request-scope beans will therefore work correctly but apps with session-scoped beans
- will still suffer confusion.</p></li>
- </ul>
- </p>
-
- <p>
- The Tomahawk library provides a partial solution to this conversation problem with
- the t:saveState tag, which allows data stored in request scope to be passed
- through to a subsequent request. However this can be difficult to use, as every
- bean that needs to be part of the conversation needs to be explicitly tracked.
- </p>
-
- <p>
- The Orchestra library provides another alternative.
- This solution works across all JSF implementations (particularly Apache MyFaces and
- the Sun Reference Implementation). It works for Java 1.4 or later. If java1.5 is
- being used then custom annotations are available to make its use even easier.
- </p>
-
- <p>
- Orchestra does require conversation-scoped managed beans to be declared via a good
- dependency-injection (aka IOC) framework with AOP support. The standard JSF
- managed-beans facility does not provide sufficient flexibility. While it should be
- possible for Orchestra to be integrated with any appropriate such framework it
- initially supports only Spring 2.x. This is no great drawback as there are many
- other good reasons to use Spring! In the remainder of this document we shall
- assume Spring is the dependency-injection framework being used.
- </p>
-
- <p>
- Various other projects (JBoss Seam, Apache Shale Dialogs, Spring WebFlow) provide
- conversation/dialog support that is similar to Orchestra. See the Orchestra wiki pages
- for up-to-date comparisons of Orchestra with other projects.
- </p>
- </section>
-
- <section name="Orchestra Conversation Scope Features">
- <p>
- The normal behaviour for JSF is that when an EL expression references a
- bean that cannot be found anywhere in the current scopes, the managed bean
- declarations are searched for the specified name. If a match is found then
- the bean declaration is used to create an appropriate object instance and
- insert it into the appropriate scope. The JSF standard provides a way for
- variable lookup to be extended, and Spring provides an adapter that makes Spring
- bean declarations accessable to JSF just like managed beans declared in the standard manner.
- </p>
-
- <p>
- While "managed beans" declared using the standard JSF syntax can only be declared with
- app, session or request scope it is possible with Spring 2.0 to declare custom scopes.
- Orchestra makes "conversation scopes" available for use. When a bean is instantiated
- which is declared to be part of "conversation Foo" then the conversation with that name
- is looked up and the bean inserted into it. This scope is user-specific (ie is a child
- of the session scope) and is created if it doesn't yet exist.
- </p>
-
- <p>
- So far, the effect is just the same as using <i>session</i> scope for these beans.
- However a conversation acts as a <i>container</i> for all the beans configured
- with a particular conversation name. When a conversation ends, all beans
- associated with that conversation can then be discarded together which is
- difficult to achieve with simple session storage. A conversation can be
- terminated in a number of ways:
- <ul>
- <li><p>access-scoped conversations end when a request occurs that does not access any bean in that conversation;</p></li>
- <li><p>a JSF endConversation component is provided that can be inserted into a page;</p></li>
- <li><p>a direct call can be made from a backing bean, eg after performing a "save" or "cancel" operation;</p></li>
- <li><p>a conversation timeout can be configured to automatically expire conversations after a specified time limit.</p></li>
- </ul>
- And as conversations have names, multiple conversations (bean groupings) can exist concurrently.
- </p>
-
- <p>
- Conversation names are declared simply by specifying attribute orchestra:conversationName on
- the Spring bean definition. If no name is provided, then the bean is placed in its own
- private conversation (which happens to have a name equal to the bean name).
- </p>
-
- <p>
- A conversation can have a <i>lifetime</i> of "access" or "manual".
- An access-scoped conversation is automatically ended (ie deleted) if a request is executed
- which does not reference any bean in that conversation's scope. This is
- very convenient when a sequence of pages all have at least one reference
- to a bean of that conversation scope. If the user navigates to any other
- page (via direct url entry, or clicking a link, etc) then after that new page is
- rendered the old (obsolete) conversation scope is automatically discarded. Only
- when a user's path through the application can reference pages that do not reference
- conversation-scoped beans is the "manual" conversation necessary - and in that case, an
- explicit endConversation component (or direct API call) must be used to discard beans
- when no longer needed.
- </p>
-
- <p>
- Orchestra also provides the concept of a "conversation context", which holds
- a set of named conversations. A "separateConversationContext" JSF component
- creates a new context. When this is a parent of any command component
- (eg a commandLink) then a new conversation context is automatically
- created when that command is executed. This allows multiple windows
- to access the same site while having completely independent sets of
- objects that are of "conversation scope". A hidden "id" emitted into
- pages specifies what the current conversation context is, ensuring the
- new windows "sticks" with its associated conversation context.
- </p>
- </section>
- </body>
+ <properties>
+ <title>Apache MyFaces Orchestra - The Conversation Scope Problem</title>
+ </properties>
+
+ <body>
+ <section name="The Conversation Scope Problem">
+ <p>
+ Often a logical operation consists of multiple JSF requests to the server.
+ For example, purchasing an insurance policy requires completing a number
+ of related forms (often referred to as a "conversation", "workflow" or
+ "dialog"), during which the same java objects need to be kept in memory.
+ </p>
+
+ <p>
+ However JSF provides only three scopes for data to be stored in:
+ <ul>
+ <li><p>Application scope</p></li>
+ <li><p>Session scope</p></li>
+ <li><p>Request scope</p></li>
+ </ul>
+ </p>
+
+ <p>
+ Application scope is only rarely of use; such data is shared across all users of that JSF application.
+ Request scope is not useful for the above scenario; all data stored in request scope is discarded at
+ the end of each "command".
+ </p>
+
+ <p>
+ Session scope can be used to hold data across multiple requests (a conversation),
+ but suffers from a number of other issues:
+ <ul>
+ <li><p>When the conversation is complete, it is best to discard all the related objects in order
+ to save memory. However this is quite difficult to do when using session scope.</p></li>
+ <li><p>When a user performs some task for a second time (eg purchasing a second insurance policy),
+ it is usually better for the backing beans to be new instances rather than having whatever
+ state they had at the end of the previous pass. This is difficult to achieve when the beans
+ are in session scope; every relevant bean needs to be explicitly deleted or reset. However
+ when these objects are stored in a conversation this happens automatically as the conversation
+ (with all its beans) has been discarded.</p></li>
+ <li><p>The user cannot have multiple windows open on the same site. Sessions are typically
+ tracked using cookies, and all windows associated with the same browser instance
+ share cookies and therefore are within the same "session". If two windows are created
+ for the same session then very strange effects can be caused due to the same "backing beans"
+ being used by the two windows. Note that JSF implementations generally provide support for
+ multiple concurrent windows (eg MyFaces and Sun RI) but this only means that the JSF
+ *components* are safe for use with multiple windows; any application that uses only
+ request-scope beans will therefore work correctly but apps with session-scoped beans
+ will still suffer confusion.</p></li>
+ </ul>
+ </p>
+
+ <p>
+ The Tomahawk library provides a partial solution to this conversation problem with
+ the t:saveState tag, which allows data stored in request scope to be passed
+ through to a subsequent request. However this can be difficult to use, as every
+ bean that needs to be part of the conversation needs to be explicitly tracked.
+ </p>
+
+ <p>
+ The Orchestra library provides another alternative.
+ This solution works across all JSF implementations (particularly Apache MyFaces and
+ the Sun Reference Implementation). It works for Java 1.4 or later. If java1.5 is
+ being used then custom annotations are available to make its use even easier.
+ </p>
+
+ <p>
+ Orchestra does require conversation-scoped managed beans to be declared via a good
+ dependency-injection (aka IOC) framework with AOP support. The standard JSF
+ managed-beans facility does not provide sufficient flexibility. While it should be
+ possible for Orchestra to be integrated with any appropriate such framework it
+ initially supports only Spring 2.x. This is no great drawback as there are many
+ other good reasons to use Spring! In the remainder of this document we shall
+ assume Spring is the dependency-injection framework being used.
+ </p>
+
+ <p>
+ Various other projects (JBoss Seam, Apache Shale Dialogs, Spring WebFlow) provide
+ conversation/dialog support that is similar to Orchestra. See the Orchestra wiki pages
+ for up-to-date comparisons of Orchestra with other projects.
+ </p>
+ </section>
+
+ <section name="Orchestra Conversation Scope Features">
+ <p>
+ The normal behaviour for JSF is that when an EL expression references a
+ bean that cannot be found anywhere in the current scopes, the managed bean
+ declarations are searched for the specified name. If a match is found then
+ the bean declaration is used to create an appropriate object instance and
+ insert it into the appropriate scope. The JSF standard provides a way for
+ variable lookup to be extended, and Spring provides an adapter that makes Spring
+ bean declarations accessable to JSF just like managed beans declared in the standard manner.
+ </p>
+
+ <p>
+ While "managed beans" declared using the standard JSF syntax can only be declared with
+ app, session or request scope it is possible with Spring 2.0 to declare custom scopes.
+ Orchestra makes "conversation scopes" available for use. When a bean is instantiated
+ which is declared to be part of "conversation Foo" then the conversation with that name
+ is looked up and the bean inserted into it. This scope is user-specific (ie is a child
+ of the session scope) and is created if it doesn't yet exist.
+ </p>
+
+ <p>
+ So far, the effect is just the same as using <i>session</i> scope for these beans.
+ However a conversation acts as a <i>container</i> for all the beans configured
+ with a particular conversation name. When a conversation ends, all beans
+ associated with that conversation can then be discarded together which is
+ difficult to achieve with simple session storage. A conversation can be
+ terminated in a number of ways:
+ <ul>
+ <li><p>access-scoped conversations end when a request occurs that does not access any bean in that conversation;</p></li>
+ <li><p>a JSF endConversation component is provided that can be inserted into a page;</p></li>
+ <li><p>a direct call can be made from a backing bean, eg after performing a "save" or "cancel" operation;</p></li>
+ <li><p>a conversation timeout can be configured to automatically expire conversations after a specified time limit.</p></li>
+ </ul>
+ And as conversations have names, multiple conversations (bean groupings) can exist concurrently.
+ </p>
+
+ <p>
+ Conversation names are declared simply by specifying attribute orchestra:conversationName on
+ the Spring bean definition. If no name is provided, then the bean is placed in its own
+ private conversation (which happens to have a name equal to the bean name).
+ </p>
+
+ <p>
+ A conversation can have a <i>lifetime</i> of "access" or "manual".
+ An access-scoped conversation is automatically ended (ie deleted) if a request is executed
+ which does not reference any bean in that conversation's scope. This is
+ very convenient when a sequence of pages all have at least one reference
+ to a bean of that conversation scope. If the user navigates to any other
+ page (via direct url entry, or clicking a link, etc) then after that new page is
+ rendered the old (obsolete) conversation scope is automatically discarded. Only
+ when a user's path through the application can reference pages that do not reference
+ conversation-scoped beans is the "manual" conversation necessary - and in that case, an
+ explicit endConversation component (or direct API call) must be used to discard beans
+ when no longer needed.
+ </p>
+
+ <p>
+ Orchestra also provides the concept of a "conversation context", which holds
+ a set of named conversations. A "separateConversationContext" JSF component
+ creates a new context. When this is a parent of any command component
+ (eg a commandLink) then a new conversation context is automatically
+ created when that command is executed. This allows multiple windows
+ to access the same site while having completely independent sets of
+ objects that are of "conversation scope". A hidden "id" emitted into
+ pages specifies what the current conversation context is, ensuring the
+ new windows "sticks" with its associated conversation context.
+ </p>
+ </section>
+ </body>
</document>
Modified: myfaces/orchestra/trunk/core/src/site/xdoc/faqs.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/faqs.xml?rev=631219&r1=631218&r2=631219&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/faqs.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/faqs.xml Tue Feb 26 06:10:33 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//Apache Software Foundation//DTD XDOC 1.0//EN"
- "http://www.apache.org/dtd/xdoc.dtd">
+ "http://www.apache.org/dtd/xdoc.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -21,100 +21,100 @@
-->
<document>
- <properties>
- <title>Apache MyFaces Orchestra - FAQs</title>
- </properties>
-
- <body>
- <section name="FAQ">
-
- <subsection name="Database connection not passed back to the connection pool after the HTTP request">
-
- <p>
- Depending on your environment and used JPA-implementation you might experience the problem
- that there are database connections which have not been passed back to the connection pool.<br />
- This can happen if you use entities with e.g. OneToMany mappings and lazy init AND accessing the
- OneToMany collection from your JSF view the first time.<br />
- The EntityManager has to re-establish a connection to your database, but now that this happens
- outside of your conversation scoped bean, no one ends the transaction and so no one puts the
- connection back to the pool.<br />
- The problem is that with a growing number of users and a growing number of conversations
- (especially not ended conversations - waiting for their timeout) your pool might exhaust.<br />
- As said before, this might not be the case with all JPA-implementations. But we had at least
- one environment where this happened, so here the work-around.
- </p>
- <p>
- To activate the workaround simply put the following code in your spring config and adjust the
- names as required.
+ <properties>
+ <title>Apache MyFaces Orchestra - FAQs</title>
+ </properties>
+
+ <body>
+ <section name="FAQ">
+
+ <subsection name="Database connection not passed back to the connection pool after the HTTP request">
+
+ <p>
+ Depending on your environment and used JPA-implementation you might experience the problem
+ that there are database connections which have not been passed back to the connection pool.<br />
+ This can happen if you use entities with e.g. OneToMany mappings and lazy init AND accessing the
+ OneToMany collection from your JSF view the first time.<br />
+ The EntityManager has to re-establish a connection to your database, but now that this happens
+ outside of your conversation scoped bean, no one ends the transaction and so no one puts the
+ connection back to the pool.<br />
+ The problem is that with a growing number of users and a growing number of conversations
+ (especially not ended conversations - waiting for their timeout) your pool might exhaust.<br />
+ As said before, this might not be the case with all JPA-implementations. But we had at least
+ one environment where this happened, so here the work-around.
+ </p>
+ <p>
+ To activate the workaround simply put the following code in your spring config and adjust the
+ names as required.
- <pre>
+ <pre>
<bean id="managedDataSource" class="org.apache.myfaces.orchestra.connectionManager.ConnectionManagerDataSource">
- <property name="dataSource" ref="dataSource"/>
+ <property name="dataSource" ref="dataSource"/>
</bean>
- </pre>
+ </pre>
- The basic principle is to put a virtual DataSource between the JPA-implementation and
- the read DataSource (which should be a connection pool for performance reasons).<br />
+ The basic principle is to put a virtual DataSource between the JPA-implementation and
+ the read DataSource (which should be a connection pool for performance reasons).<br />
- You have to configure
- <ul>
- <li><p>the property <code>dataSource</code> to point to the original datasource and</p></li>
- <li><p>the JPA configuration to use our <code>managedDataSource</code> (adjust the name if required)</p></li>
- </ul>
- </p>
- </subsection>
-
- <subsection name="PropertyPlaceholderConfigurer STOPS working after the introduction of orchestra into my configuration">
- <p>
- Use the <code><aop:scoped-proxy></code> configuratino with in the
- <code>persistentContextConversationInterceptor</code> definition.
- You'll end up with something like:
- <pre>
+ You have to configure
+ <ul>
+ <li><p>the property <code>dataSource</code> to point to the original datasource and</p></li>
+ <li><p>the JPA configuration to use our <code>managedDataSource</code> (adjust the name if required)</p></li>
+ </ul>
+ </p>
+ </subsection>
+
+ <subsection name="PropertyPlaceholderConfigurer STOPS working after the introduction of orchestra into my configuration">
+ <p>
+ Use the <code><aop:scoped-proxy></code> configuratino with in the
+ <code>persistentContextConversationInterceptor</code> definition.
+ You'll end up with something like:
+ <pre>
<bean id="persistentContextConversationInterceptor" class="org.apache.myfaces.orchestra.conversation.spring.PersistenceContextConversationInterceptor">
<aop:scoped-proxy/>
<property name="persistenceContextFactory" ref="persistentContextFactory"/>
</bean>
- </pre>
- </p>
- <p>
- The reason is, that, during startup of the spring system when the custom scope will
- be initialized, the system might already require a datasource, but at this time
- the <code>PropertyPlaceholderConfigurer</code> didn't run already.<br />
- Using the <code><aop:scoped-proxy></code> configuration allows the initialization
- process to end cleanly.
- </p>
- </subsection>
-
- <subsection name="The ViewController events are called twice">
- <p>
- If your ViewController event methods are called twice you probably configured the
- ViewControllerPhaseListener in your faces-config.xml which is not required.<br />
- Orchestra already does this for you.
- </p>
- </subsection>
-
- <subsection name="Is it possible to pass a persistent entity between beans in different conversations?">
- <p><br>No!</br></p>
- <p>
- Each conversation has its own persistence context, but an entity can only be managed
- by the context it was loaded by.
- <br/>
- Reading an entity may trigger lazy loads. This will always be performed using the
- persistence context that loaded the entity, ie this works regardless of who calls
- the method on the entity.
- <br/>
- However performing operations like merge, delete, etc. require the object to be
- passed to a persistence context; if it is passed to the wrong one then unexpected
- behaviour will occur. Things like using the object in a query being executed in
- a persistence context that is not the one associated with that entity may also
- fail.
- <br/>
- Rather than passing entity references between conversations, just pass the key of the
- object and reload it if access is required from a different conversation.
- <br/>
- This is not an Orchestra limitation, but more a technical limitation of how ORMs work today.
- </p>
- </subsection>
- </section>
- </body>
-</document>
\ No newline at end of file
+ </pre>
+ </p>
+ <p>
+ The reason is, that, during startup of the spring system when the custom scope will
+ be initialized, the system might already require a datasource, but at this time
+ the <code>PropertyPlaceholderConfigurer</code> didn't run already.<br />
+ Using the <code><aop:scoped-proxy></code> configuration allows the initialization
+ process to end cleanly.
+ </p>
+ </subsection>
+
+ <subsection name="The ViewController events are called twice">
+ <p>
+ If your ViewController event methods are called twice you probably configured the
+ ViewControllerPhaseListener in your faces-config.xml which is not required.<br />
+ Orchestra already does this for you.
+ </p>
+ </subsection>
+
+ <subsection name="Is it possible to pass a persistent entity between beans in different conversations?">
+ <p><br>No!</br></p>
+ <p>
+ Each conversation has its own persistence context, but an entity can only be managed
+ by the context it was loaded by.
+ <br/>
+ Reading an entity may trigger lazy loads. This will always be performed using the
+ persistence context that loaded the entity, ie this works regardless of who calls
+ the method on the entity.
+ <br/>
+ However performing operations like merge, delete, etc. require the object to be
+ passed to a persistence context; if it is passed to the wrong one then unexpected
+ behaviour will occur. Things like using the object in a query being executed in
+ a persistence context that is not the one associated with that entity may also
+ fail.
+ <br/>
+ Rather than passing entity references between conversations, just pass the key of the
+ object and reload it if access is required from a different conversation.
+ <br/>
+ This is not an Orchestra limitation, but more a technical limitation of how ORMs work today.
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
Modified: myfaces/orchestra/trunk/core/src/site/xdoc/glossary.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/glossary.xml?rev=631219&r1=631218&r2=631219&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/glossary.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/glossary.xml Tue Feb 26 06:10:33 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//Apache Software Foundation//DTD XDOC 1.0//EN"
- "http://www.apache.org/dtd/xdoc.dtd">
+ "http://www.apache.org/dtd/xdoc.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -21,152 +21,152 @@
-->
<document>
- <properties>
- <title>Apache MyFaces Orchestra - Glossary</title>
- </properties>
-
- <body>
- <section
- name="Glossary">
- <ul>
- <li>POJO
- <br/>
- A plain-old-Java-object, according to the Java bean standard.
- This is a class with (mostly) private members and a get- and set-method
- (also called getter and setter) for each of them. The original aim
- of object-relational mapping tools was to persist such pojos into the database with the
- help of e.g. an external xml configuration per pojo. When Java 5 came
- up this changed a bit, now it is common to use annotations in the Java
- source itself. With that, strictly spoken, beans are not pojos anymore.
- </li>
-
- <li>Entity
- <br/>
- A pojo with an extended description. The description allows the entitiy
- manger to persist the entity into the database. Common
- descriptions are XML files or annotations in the Java source. This
- data is called metadata.
- </li>
-
- <li>Property
- <br/>
- A property is a member variable of your pojo with a defined
- set and get method. You have to follow the Java Bean
- specification. The following examples show this syntax -
- the first column, named property, shows how you would access
- this property from the outside (e.g. via reflection or from a JSF-JSP-page).
- The second column shows the syntax of defining the member, the next columns
- the name of getter and setter.
- <table width="40%">
- <tr>
- <th>property</th>
-
- <th>member</th>
-
- <th>getter</th>
-
- <th>setter</th>
- </tr>
-
- <tr>
- <td>userId</td>
-
- <td>private String userId</td>
-
- <td>getUserId</td>
-
- <td>setUserId</td>
- </tr>
-
- <tr>
- <td>userName</td>
-
- <td>private String _userName</td>
-
- <td>getUserName</td>
-
- <td>setUserName</td>
- </tr>
-
- <tr>
- <td>displayed</td>
-
- <td>private boolean displayed</td>
-
- <td>isDisplayed</td>
-
- <td>setDisplayed</td>
- </tr>
-
- </table>
- </li>
-
- <li>Entity Manager
- <br/>
- The "entity manager" manages all your entities,
- keeps track of property updates and issues the database statements
- required to synchronize the entity state with the database. If you
- close an entity manager you will loose the coupling between its
- internal state and your entities, they are so called "detached objects"
- afterwards.
- </li>
-
- <li>Entity Manager Factory
- <br/>
- The "entity manager factory" is
- responsible for processing all the entity metadata and to create an
- entity manager based on it.
- </li>
-
- <li>DAO - Data Access Object
- <br/>
- Usage of data access objects is based on the pattern with the same name. Data access
- objects are singletons which contain
- all of the database requests your application will issue - generally, one data access object
- encapsulates all database requests for one entity.
- Thus, the DAO is injected with an entity
- manager.
- </li>
-
- <li>Conversation
- <br/>
- A conversation is the time-span encapsulating all the
- operations in your business logic required to finish a process
- (in the end, this will almost always include the need for executing database transactions).
- Other names of this principle are: application transaction, unit-of-work
- </li>
-
- <li>Session Scope
- <br/>
- The session scope of your servlet container.
- Beans put into this scope live until the configured inactivity timout
- for the session has been reached or the session is closed explicitly
- </li>
-
- <li>Request Scope
- <br/>
- The request scope of your servlet container.
- The lifetime of request-scoped-beans is as long as the duration of a
- single HTTP request. Once the servlet container finishes sending
- the page data, the request will die and with it all the beans put into
- this scope.
- </li>
-
- <li>JPA - Java Persistence API
- <br/>
- The JPA standardizes the way how
- you annotate your entities with regards to persistence. That way you can change the
- ORM tool as long as the ORM tool follows the JPA
- specification.
- </li>
-
- <li>backing bean
- <br/>
- A backing bean is the bean behind a JSF view
- (jsp, facelet, etc page). While JSF does not require such a bean, it is
- good practice to provide one backing-bean per page as a rule of thumb.
- </li>
- </ul>
- </section>
- </body>
+ <properties>
+ <title>Apache MyFaces Orchestra - Glossary</title>
+ </properties>
+
+ <body>
+ <section
+ name="Glossary">
+ <ul>
+ <li>POJO
+ <br/>
+ A plain-old-Java-object, according to the Java bean standard.
+ This is a class with (mostly) private members and a get- and set-method
+ (also called getter and setter) for each of them. The original aim
+ of object-relational mapping tools was to persist such pojos into the database with the
+ help of e.g. an external xml configuration per pojo. When Java 5 came
+ up this changed a bit, now it is common to use annotations in the Java
+ source itself. With that, strictly spoken, beans are not pojos anymore.
+ </li>
+
+ <li>Entity
+ <br/>
+ A pojo with an extended description. The description allows the entitiy
+ manger to persist the entity into the database. Common
+ descriptions are XML files or annotations in the Java source. This
+ data is called metadata.
+ </li>
+
+ <li>Property
+ <br/>
+ A property is a member variable of your pojo with a defined
+ set and get method. You have to follow the Java Bean
+ specification. The following examples show this syntax -
+ the first column, named property, shows how you would access
+ this property from the outside (e.g. via reflection or from a JSF-JSP-page).
+ The second column shows the syntax of defining the member, the next columns
+ the name of getter and setter.
+ <table width="40%">
+ <tr>
+ <th>property</th>
+
+ <th>member</th>
+
+ <th>getter</th>
+
+ <th>setter</th>
+ </tr>
+
+ <tr>
+ <td>userId</td>
+
+ <td>private String userId</td>
+
+ <td>getUserId</td>
+
+ <td>setUserId</td>
+ </tr>
+
+ <tr>
+ <td>userName</td>
+
+ <td>private String _userName</td>
+
+ <td>getUserName</td>
+
+ <td>setUserName</td>
+ </tr>
+
+ <tr>
+ <td>displayed</td>
+
+ <td>private boolean displayed</td>
+
+ <td>isDisplayed</td>
+
+ <td>setDisplayed</td>
+ </tr>
+
+ </table>
+ </li>
+
+ <li>Entity Manager
+ <br/>
+ The "entity manager" manages all your entities,
+ keeps track of property updates and issues the database statements
+ required to synchronize the entity state with the database. If you
+ close an entity manager you will loose the coupling between its
+ internal state and your entities, they are so called "detached objects"
+ afterwards.
+ </li>
+
+ <li>Entity Manager Factory
+ <br/>
+ The "entity manager factory" is
+ responsible for processing all the entity metadata and to create an
+ entity manager based on it.
+ </li>
+
+ <li>DAO - Data Access Object
+ <br/>
+ Usage of data access objects is based on the pattern with the same name. Data access
+ objects are singletons which contain
+ all of the database requests your application will issue - generally, one data access object
+ encapsulates all database requests for one entity.
+ Thus, the DAO is injected with an entity
+ manager.
+ </li>
+
+ <li>Conversation
+ <br/>
+ A conversation is the time-span encapsulating all the
+ operations in your business logic required to finish a process
+ (in the end, this will almost always include the need for executing database transactions).
+ Other names of this principle are: application transaction, unit-of-work
+ </li>
+
+ <li>Session Scope
+ <br/>
+ The session scope of your servlet container.
+ Beans put into this scope live until the configured inactivity timout
+ for the session has been reached or the session is closed explicitly
+ </li>
+
+ <li>Request Scope
+ <br/>
+ The request scope of your servlet container.
+ The lifetime of request-scoped-beans is as long as the duration of a
+ single HTTP request. Once the servlet container finishes sending
+ the page data, the request will die and with it all the beans put into
+ this scope.
+ </li>
+
+ <li>JPA - Java Persistence API
+ <br/>
+ The JPA standardizes the way how
+ you annotate your entities with regards to persistence. That way you can change the
+ ORM tool as long as the ORM tool follows the JPA
+ specification.
+ </li>
+
+ <li>backing bean
+ <br/>
+ A backing bean is the bean behind a JSF view
+ (jsp, facelet, etc page). While JSF does not require such a bean, it is
+ good practice to provide one backing-bean per page as a rule of thumb.
+ </li>
+ </ul>
+ </section>
+ </body>
</document>