You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/04/17 03:29:53 UTC
svn commit: r1326868 [2/2] - in /myfaces/orchestra/trunk: core/src/site/
core/src/site/xdoc/ maven/src/site/ maven/src/site/xdoc/
Added: myfaces/orchestra/trunk/maven/src/site/xdoc/installation.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/maven/src/site/xdoc/installation.xml?rev=1326868&view=auto
==============================================================================
--- myfaces/orchestra/trunk/maven/src/site/xdoc/installation.xml (added)
+++ myfaces/orchestra/trunk/maven/src/site/xdoc/installation.xml Tue Apr 17 01:29:52 2012
@@ -0,0 +1,314 @@
+<?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">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+<document>
+ <properties>
+ <title>Apache MyFaces Orchestra - Installation</title>
+ </properties>
+
+ <body>
+ <section name="Installation">
+ In the following, we will assume that you know how to setup
+ <ul>
+ <li><p>a servlet container (Tomcat, Jetty, etc)</p></li>
+ <li><p>your ORM tool (OpenJPA, Toplink.essentials, Hibernate, etc)</p></li>
+ <li><p>your JSF implementation (MyFaces, JSF-RI, etc)</p></li>
+ </ul>
+ <p>
+ For a beginner these are big assumptions; none of these technologies are simple.
+ However we simply cannot conver these topics in a brief guide. In addition, these
+ subjects are covered well elsewhere.
+ </p>
+ <p>
+ For an absolute beginner in using these technologies, we recommend taking a look at the
+ <a href="http://code.google.com/p/facesgoodies/">Faces-Goodies</a> project - a perfect way
+ of kickstarting you in the world of JSF, Spring and JPA and then return back to include Apache
+ Orchestra.
+ </p>
+ <p>
+ The installation guide will show you how to setup a JPA entity manager for Orchestra (so you are
+ working with the new JavaPersistence API standard). Later we hope to add chapters on integrating
+ directly with Hibernate and Toplink.
+ </p>
+
+ <subsection name="Prerequisites">
+ <ul>
+ <li><p>Apache MyFaces Orchestra core</p></li>
+ <li><p>Apache MyFaces Orchestra core15 (optional; requires java1.5 or later)</p></li>
+ <li><p>Spring 2.x</p></li>
+ <li><p>a JSF implementation (e.g. JSF-RI, MyFaces)</p></li>
+ <li><p>a JPA implementation (e.g. OpenJPA, toplink.essentials (formerly
+ Oracle Toplink)</p></li>
+ <li><p>and all their dependencies
+ <br/>
+ This might sound somehow vague; however, the exact names of the necessary libraries
+ depends on the JSF and JPA implementation. If you have to setup
+ an application architecture like this from scratch it might be best to take a look at our
+ examples package, and there in the file "pom.xml" which includes a section on the
+ necessary dependencies.</p>
+ </li>
+ </ul>
+ </subsection>
+
+ <subsection name="Spring Configuration">
+ <p>
+ Apache MyFaces Orchestra uses the powerful Spring framework to provide its conversation scope.
+ Spring is a dependency injection framework - just like the JSF managed-bean facility which
+ is configured in the faces-config files of traditional JSF applications.
+ However Spring offers many very nice additional features, including some that are
+ essential for Apache Orchestra. In particular it allows us to create a new scope-type.
+ </p>
+ <p>
+ Lets start with the Spring configuration for the conversation scope and the JPA entity-manager
+ factory. This configuration file has to be placed into the WEB-INF directory of your web
+ application using the name applicationContext.xml. This can be configured with a
+ context-parameter in your web.xml; for more information, take a look at the Spring documentation.
+ </p>
+ <pre>
+<![CDATA[
+ <?xml version="1.0" encoding="UTF-8"?>
+
+ <beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ 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">
+
+ <!-- 1. initialization of all orchestra modules (required for core15 module) -->
+ <import resource="classpath*:/META-INF/spring-orchestra-init.xml" />
+
+ <!-- 2. the conversation scopes -->
+ <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
+ <property name="scopes">
+ <map>
+ <entry key="conversation.manual">
+ <bean class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
+ <property name="timeout" value="30" />
+ <property name="advices">
+ <list>
+ <ref bean="persistentContextConversationInterceptor"/>
+ </list>
+ </property>
+ </bean>
+ </entry>
+
+ <entry key="conversation.access">
+ <bean class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
+ <property name="timeout" value="30" />
+ <property name="advices">
+ <list>
+ <ref bean="persistentContextConversationInterceptor"/>
+ </list>
+ </property>
+ <property name="lifetime" value="access"/>
+ </bean>
+ </entry>
+ </map>
+ </property>
+ </bean>
+
+ <!-- 3. the "entity manager" manager -->
+ <bean id="persistentContextConversationInterceptor"
+ class="org.apache.myfaces.orchestra.conversation.spring.PersistenceContextConversationInterceptor">
+ <property name="persistenceContextFactory" ref="persistentContextFactory"/>
+ </bean>
+
+ <!-- 4. conversation - persistence adapter -->
+ <bean id="persistentContextFactory"
+ class="org.apache.myfaces.orchestra.conversation.spring.JpaPersistenceContextFactory">
+ <property name="entityManagerFactory" ref="entityManagerFactory"/>
+ </bean>
+
+ <!-- 5. persistence -->
+ <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
+
+ <tx:annotation-driven />
+
+ <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+ <property name="entityManagerFactory" ref="entityManagerFactory"/>
+ </bean>
+
+ <bean id="entityManagerFactory"
+ class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
+ <property name="jpaProperties">
+ <props>
+ <prop key="toplink.logging.level">FINE</prop>
+ <prop key="toplink.jdbc.driver">org.apache.derby.jdbc.EmbeddedDriver</prop>
+ <prop key="toplink.jdbc.url">jdbc:derby:myfacesOrchestraDB;create=true</prop>
+ <prop key="toplink.jdbc.user">sa</prop>
+ <prop key="toplink.jdbc.password">foobar</prop>
+ <prop key="toplink.target-database">oracle.toplink.essentials.platform.database.DerbyPlatform</prop>
+ <prop key="toplink.ddl-generation">create-tables</prop>
+ </props>
+ </property>
+ <property name="persistenceUnitName" value="default"/>
+ </bean>
+ </beans>
+ ]]>
+</pre>
+ <p>
+ Basically, all you need to do is copy this configuration segment and paste it
+ into your Spring configuration file. Then you'll need to adapt the settings in the element
+ entityManagerFactory - namely the jpaProperties. For a more detailed explanation, we have
+ included the following instructions - it is not necessary to read through them.
+ </p>
+ <ul>
+ <li>1. initialization of orchestra modules
+ <br />
+ The Spring import statement will ensure that all <code>spring-orchestra-init.xml</code>
+ files are processed. Orchestra sets up some defaults in these init files that are
+ necessary for the correct functioning of Orchestra.
+ </li>
+ <li>2. the conversation scopes
+ <br/>
+ Here we configure both "conversation.access" and "conversation.manual" as new Spring
+ custom scopes. This configuration allows us to use scope="conversation.access"
+ or scope="conversation.manual" within our bean declarations. The scope definition
+ also allows a number of advices (interceptors) to be configured; advices intercept
+ each method call to a bean in that scope. We add an interceptor here to ensure that
+ on any call to a bean in that scope the entity manager (aka persistence context) is
+ set to be the appropriate one for that conversation.
+ <br/>
+ If your application does not have to deal with persistence, and you would still like to use
+ the conversation scopes you can delete the advices from this configuration.
+ <br />
+ Optionally you can configure the timeout used to automatically end a conversation.
+ The <code>timeout</code> property accepts a numeric value which means a timespan
+ in minutes.
+ <br />
+ Notice: <b>Without this timeout configuration, a manual conversation won't die if you do
+ not explicitly end it using the conversation API.</b>
+ </li>
+
+ <li>3. the "persistence context conversation interceptor"
+ <br/>
+ This tells spring what class to use for the interceptor specified in the scope
+ definitions. This orchestra class does the hard work of keeping the right
+ persistence context set up at all times.
+ </li>
+
+ <li>4. conversation - persistence adapter
+ <br/>
+ Depending on the ORM tool you want to use you will have to configure an appropriate
+ persistenceContextFactory. Apache MyFaces Orchestra provides a JPA implementation
+ in its current release; other adapters may be added in the future.
+ </li>
+
+ <li>5.persistence
+ <br/>
+ This enables the standard Spring support for persistence annotations such as
+ @PersistenceContext; any bean instantiated by spring will be scanned for
+ annotations and the appropriate dependencies injected.
+ <br/>
+ This section also sets up database transaction support.
+ <br/>
+ As this is all standard Spring functionality, have a look at the Spring
+ documentation for further details and options. For our example, we use
+ <code><tx:annotation-driven/></code>.
+ <br/>
+ If you are using Java 1.4 you can choose a non-annotation-based approach.
+ </li>
+ </ul>
+ <p>
+ <b>Notice</b>
+ : You will be able to configure multiple conversation
+ scopes (each one of them will need to have a distinct name)
+ using different persistence strategies or without persistence at all.
+ </p>
+ <p>That's all for Spring now -
+ according to the JPA specification and your JPA implementation, you will also
+ have to provide a META-INF/persistence.xml too. Please check your JPA provider
+ documentation on how to do this.
+ </p>
+ </subsection>
+ <subsection name="JSF configuration">
+ <p>
+ Next you have to add some listeners to your web.xml configuration.
+ </p>
+ <pre>
+<![CDATA[
+<listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+</listener>
+<listener>
+ <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
+</listener>
+<listener>
+ <listener-class>org.apache.myfaces.orchestra.conversation.servlet.ConversationManagerSessionListener</listener-class>
+</listener>
+]]>
+ </pre>
+ </subsection>
+
+ <subsection name="Mixed environment installation">
+ <p>
+ If your application has only JSF pages then no further configuration is required.
+ </p>
+ <p>
+ However if your application includes jsp, plain servlets, or anything else that
+ does not pass through the FacesServlet then two filters must be defined:
+ </p>
+<pre>
+<![CDATA[
+ <filter>
+ <filter-name>frameworkAdapterFilter</filter-name>
+ <filter-class>org.apache.myfaces.orchestra.frameworkAdapter.basic.BasicFrameworkAdapterFilter</filter-class>
+ </filter>
+
+ <filter>
+ <filter-name>requestParameterFilter</filter-name>
+ <filter-class>org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterServletFilter</filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>frameworkAdapterFilter</filter-name>
+ <url-pattern>*.jsp</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name>requestParameterFilter</filter-name>
+ <url-pattern>*.jsp</url-pattern>
+ </filter-mapping>
+]]></pre>
+ </subsection>
+
+ <subsection name="Conclusion">
+ That's all for the basic configuration of Apache MyFaces Orchestra; now you should have
+ working conversation scopes and correctly configured persistence. In fact there is nothing
+ special in creating the database access objects (DAO) or your business objects (BO). Your
+ JSF page backing beans will also look the same - however, you configure them in Spring and
+ put them into the conversation scope now, rather than session scope.
+ </subsection>
+
+ </section>
+ <section name="User provided configurations">
+ <ul>
+ <li><p><a href="alternative-configuration.html">A spring configuration using toplink and load time weaving with tomcat</a></p></li>
+ </ul>
+ </section>
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/maven/src/site/xdoc/installation.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: myfaces/orchestra/trunk/maven/src/site/xdoc/introduction.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/maven/src/site/xdoc/introduction.xml?rev=1326868&view=auto
==============================================================================
--- myfaces/orchestra/trunk/maven/src/site/xdoc/introduction.xml (added)
+++ myfaces/orchestra/trunk/maven/src/site/xdoc/introduction.xml Tue Apr 17 01:29:52 2012
@@ -0,0 +1,69 @@
+<?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">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+<document>
+ <properties>
+ <title>The Apache MyFaces Orchestra Core Module</title>
+ </properties>
+
+ <body>
+ <section name="Apache MyFaces Orchestra Core">
+ <p>The Orchestra Core library provides the following features as described in the
+ documentation for the Orchestra project:
+ <ul>
+ <li><p><a href="conversation.html">Conversation scope</a> (aka dialog scope) for beans.</p></li>
+ <li><p><a href="persistence.html">Conversation-scope persistence</a> contexts. This fixes the
+ dreaded LazyInitializationException or NonUniqueObjectException problems when working with
+ persistent objects.</p></li>
+ </ul>
+ </p>
+ <p>Orchestra Core requires only Java 1.4 and JSF 1.1.</p>
+ </section>
+ <section name="Important Information">
+ <p>
+ Orchestra assumes the presence of a server-side http session into which state is stored.
+ If you are designing a highly scalable distributed system then this may not be the right
+ approach for you.
+ </p>
+ <p>
+ Orchestra persistence features presume the presentation tier has access to the database,
+ ie that the presentation and database-access tiers are combined. This is often the case
+ in small-to-medium web applications. Large or security-sensitive applications which separate
+ database access out into an isolated tier (eg use a "full EJB stack") cannot use the Orchestra
+ persistence facilities, although they can still make use of the regular conversational support
+ for beans in the presentation layer.
+ </p>
+ <p>
+ Orchestra conversations with persistence support will never be transparently "distributable"; JPA
+ sessions are not serializable. However it should be possible for conversations that do not have an
+ associated persistence context to be distributed; this work has not yet been done as the current
+ Orchestra developers and users do not need this feature. If you need this feature, please contact
+ the development list.
+ </p>
+ <p>
+ Orchestra currently does not support Portlets. It should not be particularly difficult
+ to implement this, but the current Orchestra development team do not use Portlets so
+ support will only be available when someone volunteers to do the necessary work.
+ </p>
+ </section>
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/maven/src/site/xdoc/introduction.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: myfaces/orchestra/trunk/maven/src/site/xdoc/multiwindow.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/maven/src/site/xdoc/multiwindow.xml?rev=1326868&view=auto
==============================================================================
--- myfaces/orchestra/trunk/maven/src/site/xdoc/multiwindow.xml (added)
+++ myfaces/orchestra/trunk/maven/src/site/xdoc/multiwindow.xml Tue Apr 17 01:29:52 2012
@@ -0,0 +1,220 @@
+<?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">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+<document>
+ <properties>
+ <title>Dealing with Multiple Browser Windows</title>
+ </properties>
+
+ <body>
+ <section name="The General Problem">
+ <p>When the web was originally designed, sites were stateless. In addition, users would usually
+ only use a single web-browser window. Unfortunately neither of these are now true; the sites
+ that JSF and similar technologies are most useful for are highly stateful applications that
+ resemble desktop applications. And users are used to having multiple browser windows or tabs
+ open concurrently; it is simply natural for them to try to browse data with one window while
+ editing it with another. In any application this requires some programming care to handle
+ correctly, although for "desktop" applications this is not too difficult. For web applications
+ handling this is trickier, but possible as long as the server can keep track of which window
+ is performing which operations and allocate separate "state" data to each window.</p>
+ <p>When all state is embedded within a page (as form fields), or within the url (as query
+ parameters); the window identity does not need to be tracked at all as each request includes
+ all the necessary state. However there are a couple of significant problems with embedding
+ state into a page, including:
+ <ul>
+ <li>limited size of urls</li>
+ <li>the long lifetime of urls (they can be bookmarked and later reused)</li>
+ <li>state encoded into forms gets lost on GET requests (ie link anchors)</li>
+ <li>network bandwidth needed to stream state from server to client</li>
+ <li>not all state may be easily serializable (eg persistence contexts).</li>
+ </ul>
+ </p>
+ <p>Unfortunately, the http protocol has not kept up with these new changes in web usage. The
+ use of a "sessionId" embedded in either the url or a "cookie" was invented many years ago to
+ support stateful behaviour <i>per-browser</i>. However this simply does not allow a server to
+ properly provide per-window state.</p>
+ <p>There are various hacks available to handle per-window state on the server which work at
+ least partially, but none of them are completely satisfactory.</p>
+ <p>The user actions which are particularly problematic are:</p>
+ <ul>
+ <li>Right-clicking a link and selecting "open in new window" or "open in new tab"</li>
+ <li>Bookmarking a page, then later opening a new page and activating the bookmark.</li>
+ <li>Copying the URL from the browser toolbar and pasting it into a new window</li>
+ </ul>
+ <p>Note that this section is not discussing the issue of modal popup windows. Those occur
+ only where the program explicitly chooses, and so which "window state" is associated with that
+ window is under the control of the programmer and is not a major problem. It is those windows
+ that the user may open without the knowledge of the server that this page addresses.</p>
+ </section>
+
+ <section name="Orchestra and the Multiple Window Problem">
+ <p>Orchestra is explicitly intended to support stateful applications using server-side state.
+ Therefore people who are interested in using Orchestra are almost certainly also interested in dealing with
+ the general problem of multiple concurrent windows onto the stateful application.</p>
+ <p>Orchestra is also intended to provide a framework on which sophisticated "state management"
+ for applications can be built. An example is the ability to click a link in a page header to
+ save the current state, effectively providing a bookmark-with-state that the user can then
+ restore at some later time. This would allow users to "interrupt" their current task to deal with an
+ urgent call, then return to it when the interruption is dealt with. Therefore the concept of
+ state management is core; the "ConversationContext" class holds the entire set of active conversations
+ and a user can have multiple ConversationContext objects (although only one is used for any
+ particular http request). Providing per-window state management is just a matter of associating
+ a window with a particular ConversationContext.</p>
+ <p>There is also one Orchestra-specific issue related to multiple windows: the "access-scope conversation"
+ feature fails when multiple windows are sharing the same state. Access scope monitors requests and
+ automatically cleans up conversations that are no longer being used. However when two windows are
+ accessing the same orchestra-enabled webapp concurrently and use the same per-window-state, then a
+ request in one window would cause conversations to be discarded which the other window later wants
+ to use.</p>
+ <p>Orchestra therefore provides built-in support for multiple windows. Unfortunately due to the
+ limitations of http this is not a bullet-proof solution and correct handling of multiple windows
+ requires some work by the programmer and some cooperation by the end users.</p>
+ <p>See the section below titled "Orchestra Multiple Window Support" for details of the current
+ implementation provided by Orchestra.</p>
+ </section>
+
+ <section name="Embedding a window-id in a hidden field">
+ <p>The most reliable way of tracking window identity is to embed a window-id within a hidden
+ field in each form, and mark forms as using POST (which is the default). Browsers do not support
+ an operation to do "submit form and show result in other window", and bookmarking does not store
+ form data. In addition, when a POST is performed the url of the post is displayed in the browser
+ navigation bar, but not the form field values so it is not stored by a later "bookmark" operation.
+ Therefore a window identifier from one form cannot end up in another window (except by malicious
+ behaviour on the part of the user, which doesn't matter here as the user can only confuse the state
+ of their own windows, not anybody else's).</p>
+ <p>Unfortunately, the window identity will be lost as soon as the user does an operation
+ that is not a POST. And this is a critical flaw in most cases; applications that care about window
+ state generally want to allow navigation via links (GET) as well as form posts.</p>
+ <p>Even when state is only needed for POST sequences, that state does need to be cleaned up when
+ the user does a GET. Therefore losing the window identity value when a GET is done makes it
+ impossible to correctly clean up memory on the server.</p>
+ </section>
+
+ <section name="Embedding a window-id in a cookie">
+ <p>Cookies are (name,value) pairs that a server can send to a browser, and which the browser will
+ then echo back in each request that it sends to a server. These are not bookmarkable and are provided
+ on all request types (GET, POST, etc). Therefore they are ideal to track window identity - except
+ that all modern browsers treat cookies as shared across all windows in a browser. Setting it in one
+ window affects all other windows too.</p>
+ <p>There is <i>possibly</i> a way to use cookies to track window identity when javascript is enabled.
+ Below is the outline of a possible approach using cookies. However it has not been implemented at the
+ current time because it has a number of significant flaws. Together these make this approach less
+ appealing than the url-based approach that Orchestra currently implements. The limitations are:</p>
+ <ul>
+ <li>It requires javascript (though it is possible to "fall back" to other approaches).</li>
+ <li>It requires session-scoped cookies</li>
+ <li>It requires the server to detect whether the browser supports cookies or not.</li>
+ <li>It requires javascript to be rendered into the head of each page.</li>
+ </ul>
+ <p>Javascript can be used to update a cookie's value. Therefore it is possible for links to use an
+ "onclick" handler to set a cookie to contain a window-id, then perform the requested GET operation
+ and immediately reset the cookie. This causes the request to contain the needed window-id while
+ preventing the id from appearing in the page URL (where it can be bookmarked or simply copy-and-pasted).
+ In addition, the "open in new window" operation will not run the javascript so requests fetched into
+ a new window will not send a window-id and the server can detect this.</p>
+ <p>Some example code that would be rendered into the head of each page:</p>
+ <pre>
+window.document.cookie="windowId=-1";
+function docookie(link) {
+ window.document.cookie="windowId=3";
+ window.location.replace(link.href)
+ window.document.cookie="windowId=-1";
+ return false;
+}
+ </pre>
+ <p>Javascript links then look like <![CDATA[<a href="someurl" onclick="docookie(this)">..</a>]]></p>
+ </section>
+
+ <section name="Embedding a window-id in the URL">
+ <p>The window identity can be embedded within the url as a query parameter. This means that each form's
+ action url must contain the magic parameter, and so must the href of every link that is intended to be
+ clicked to perform navigation in the same frame. A request that does not contain the magic query
+ parameter is regarded as a "new window", and is allocated a new id.</p>
+ <p>Users must then be prevented from using "open in new window" on links containing the id, as that would
+ copy the magic window-id parameter and both windows would appear to the server to be the same window. This
+ can be done by setting the "href" parameter of these links to "javascript:0", and adding an onclick
+ attribute that actually does the navigation by assigning the desired url to property "window.location".
+ The FireFox browser simply does not render the "open in new window" option when the href is a javascript
+ link; Internet Explorer does render the menu option but the newly opened window is always blank.</p>
+ <p>Users will want to open new windows, however. Therefore the webapp developer can arrange for some
+ of the links to explicitly use javascript to open a new window and assign it a URL that does not have
+ the magic window-id parameter, therefore causing the request from that window to be assigned a new id.</p>
+ <p>Unfortunately this approach does have some limitations:</p>
+ <ul>
+ <li>The window-id value appears in the navigation bar, which is slightly ugly.</li>
+ <li>The window-id is saved when a bookmark is made; if two windows are opened and the same bookmark
+ activated in each then the two windows then have the same window-id. A simple copy-and-paste of the url
+ also duplicates the window-id parameter.</li>
+ <li>Javascript is required; when javascript is not enabled then the whole application becomes unusable
+ as the links are unusable (do nothing).</li>
+ </ul>
+ <p>Because of the above limitations this approach does <i>allow</i> the user to have multiple windows on
+ the same app, each with independent state, but does require them to avoid the problematic behvaiours.</p>
+ </section>
+
+ <section name="Post-render detection of Window Properties">
+ <p>When a new window is opened, a new javascript Window object is created for it. Javascript can
+ therefore check for a property on the window and if it is not set then it can assume this is a
+ new window.</p>
+ <p>This approach is reasonably simple to implement. Its major limitations are:</p>
+ <ul>
+ <li>Javascript is required</li>
+ <li>Testing can only be done <i>after</i> a page has been rendered. When the test fails (ie this
+ is a new window) then the javascript can discard the current page and request a new one from the
+ server, this time telling the server to allocate a new window-id. However if rendering of the
+ page causes side-effects on the server then these cannot be undone. In most cases this is not an
+ issue as new pages are always populated using GET requests and these should not have side-effects.
+ </li>
+ </ul>
+ <p>The server of course also needs to be told about the id, so this would need to be combined
+ with something like the "Embedding a window-id in the URL" approach. However it does work around
+ some of the limitations of that approach by detecting when a "forbidden" user operation has occurred.</p>
+ <p>This approach was (AFAIK) invented by the Apache Wicket project.</p>
+ <p>The fact that new-window-detection occurs after rendering makes this unsuitable for handling
+ multiple windows with respect to Orchestra access-scope. Access-scoped beans within the per-window-state
+ (conversation context) associated with the current window are purged following rendering of a new view;
+ unforunately if it is later discovered on the browser that this request was rendered into a new window
+ (ie should have run in a new conversation context) then it is too late to "unpurge" the conversation
+ context.</p>
+ </section>
+
+ <section name="Orchestra Multiple Window Support">
+ <p>Orchestra currently implements the "Embedding a window-id in the URL" approach. It overrides method
+ ServletResponse.encodeURL to automatically insert a query-parameter named "conversationContext" into every url
+ rendered in the page. This can be disabled for specific links using the JSF ox:separateConversationContext
+ tag around the link; the link url will not have the magic parameter in it and therefore the request will cause
+ a new context to be allocated on the server.</p>
+ </section>
+
+ <section name="Other Web Frameworks">
+ <p>In the documentation for various webapp frameworks and conversation-management libraries a claim
+ to handle multiple windows correctly is often found. However these appear to all be false. Spring
+ WebFlow, JBoss Seam and Apache Wicket all fail to handle multiple windows correctly despite statements
+ to the contrary in their documentation. This is not a flaw in their code; solving this correctly
+ appears to be impossible without a change to the http protocol. However it is a flaw in the
+ documentation. Claims by any other webapp framework to handle this issue 100% correctly should be
+ carefully analysed. If one is found that does appear to implement a perfect solution for this
+ approach, please contact the Orchestra mailing list!</p>
+ </section>
+
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/maven/src/site/xdoc/multiwindow.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: myfaces/orchestra/trunk/maven/src/site/xdoc/persistence.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/maven/src/site/xdoc/persistence.xml?rev=1326868&view=auto
==============================================================================
--- myfaces/orchestra/trunk/maven/src/site/xdoc/persistence.xml (added)
+++ myfaces/orchestra/trunk/maven/src/site/xdoc/persistence.xml Tue Apr 17 01:29:52 2012
@@ -0,0 +1,240 @@
+<?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">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+<document>
+ <properties>
+ <title>Conversation Scoped Persistence</title>
+ </properties>
+
+ <body>
+ <section name="Introduction To Conversation Scoped Persistence">
+ <p>Orchestra's persistence support aims to simplify developers life when it comes
+ to build web based applications that extensively use ORM persistence including
+ JPA (Java Persistence API), Toplink or Hibernate.</p>
+ <p>Persistent objects often participate in a conversation (ie a sequence of requests).
+ For example, an address-management module may need to read a person from a database
+ on the first request of a conversation, then later requests may modify attributes
+ and add child records for address, telephone, email, etc. Only at the end of the
+ conversation is the data saved back to the database.</p>
+ </section>
+
+ <section name="The Problem">
+ <p>Whoever has web-application development experience with an ORM layer
+ has run into exceptions like the dreaded LazyInitializationException which
+ occurs when following a relationship from one persistent object to another,
+ or the NonUniqueObjectException that occurs if you try to <code>merge</code>
+ detached objects back into the persistence session. Most of those problems,
+ if not all, result from the fact that a persistence session is opened and closed
+ for each HTTP request. In this case, the ORM tool has no chance to manage your
+ entities for the duration of a business process - once you close a persistence
+ layer session at the end of the HTTP request, all entities are detached from the
+ persistence layer session.</p>
+ <p>The magic is to keep such a persistence session open as long as required, but
+ as short as possible, contrary to the well-known OpenSessionInView or
+ OpenSessionPerRequest-patterns. In those patterns, the session is closed too early
+ for completing a full business process. Keeping the session alive for exactly the
+ necessary timespan is one of the cool features of Apache MyFaces Orchestra.</p>
+ <p>The demarcation of such a timespan is defined by a conversation in Orchestra. A
+ conversation is completely detached from the pageflow, it doesn't matter if the
+ conversation spans multiple requests on a single page or multiple pages.</p>
+ <p>A conversation scope is (like the request or session scope) a place where you can
+ store your beans. A conversation-scoped bean will have an attached entity manager
+ which is in use for each database access until the application ends the conversation.</p>
+ </section>
+
+ <section name="Quick review of the Java Persistence API (JPA)">
+ <p>JPA defines the concept of a "PersistenceContext", aka an EntityManager (or in Hibernate
+ terminology, a "Session"). This represents a pool of persistent objects. First the context
+ has to be created. Then data can be loaded from the database, causing objects to be created
+ and placed in the context. Objects in the context can be modified, and new objects can be
+ placed in the context. When entityManager.flush() is called, any modified data in the
+ context is written back out to the database.</p>
+ <p>When an object is read from the database which has a reference to some other persistent
+ object, what happens depends on whether that reference ("relation") is marked as "eager"
+ or "lazy":
+ <ul>
+ <li><p>For eager relations, the associated data is read immediately from the database,
+ and an object created to hold it (which is also added to the persistence context). The
+ relation can then be followed (ie the reference used) even after the associated
+ persistence context is no longer valid, as the object is already in memory.</p></li>
+ <li><p>For lazy relations, the reference in the original object points instead at a
+ JPA-created proxy object, and only if a method is invoked on the proxy is a database
+ operation triggered to load the actual object. Lazy relations are very useful, but mean
+ that the relation can only be followed while the persistence context is still valid; if
+ the proxy is triggered after the persistence context is no longer valid then a
+ LazyInitializationException occurs.</p></li>
+ </ul>
+ </p>
+ <p>A context can be closed (which automatically flushes it). When this happens, all objects in
+ the context become "detached"; code that holds references to them can still access the objects.
+ However because the context no longer exists, they cannot be written back to the database.
+ In addition, any attempt to fetch a related object causes a LazyIntializationException because
+ there is no longer a context into which the related object can be fetched.</p>
+ <p>Contexts are closed when no longer used because they do take up a lot of memory. The art of
+ persistence is to keep contexts around for as long as necessary but no longer. Note that in
+ some ORM implementations it is possible to partially discard contexts, ie to remove from the
+ context objects that are known to no longer be needed, but that is not a general-purpose
+ solution; it is just too hard to manually track exactly what is in use and what is not.</p>
+ <p>An object which has been detached (ie whose context has been closed) can be reattached to a
+ different context. This allows code to load an object, detach it, modify it and later
+ (potentially days later) create a new context, reattach the object then flush the new
+ context causing that object to be written to the database. Of course if the database has
+ been modified in the meantime then the save will fail.</p>
+ <p>The above information about JPA also applies to Hibernate and Toplink, which work in
+ a very similar manner.</p>
+ </section>
+
+ <section name="Using EJBs (separated web tier and business logic)">
+ <p>When using the full jee framework, the web and logic tiers are strongly separated, and may be
+ on separate physical machines. The logic tier (EJBs) are responsible for performing all
+ database access; they use declarative security and other mechanisms to ensure that external
+ code (including a web tier, native gui applications, etc) can only read data that they have
+ rights to read, and can only modify data via the APIs provided by the EJBs.</p>
+ <p>In this case, the web tier has no database connection, and clearly can only navigate relations
+ that are present in the serialized data returned by EJBs. In the old days (before JPA),
+ fields representing such relationships would simply be null, and accessing them would
+ trigger a NullPointerException or similar. If an EJB uses JPA to load objects, then
+ returns those objects to a remote client, then any attempt to navigate a relationship
+ that is not populated will instead result in a LazyInitializationException; the effect
+ is the same but the difference exists because JPA uses proxy objects to implement lazy
+ loading. These proxy objects get returned along with the "real" data, but as there is
+ no longer a context that the real referenced objects can be loaded into (and no
+ database connection to do it with!) they cannot execute.</p>
+ <p>In practice, this does mean that the EJB tier has to be very aware of the needs of its
+ presentation tier (eg the web tier), but this does seem unavoidable, and is the price
+ of the strong separation between business and presentation.</p>
+ <p>Because an application using this architecture provides no database connection to
+ the web tier, Orchestra <i>can not provide any support for conversation-scoped persistence
+ contexts</i>. Orchestra's persistence support is only for use with applications that have
+ their business logic and presentation logic in the same tier.</p>
+ <p>Note that JBoss Seam provides similar "conversation-scoped" persistence support, but this
+ also only applies when the business logic and the presentation logic are in the same
+ "tier". When remote EJBs are used to implement interactions with the database then
+ there is simply nothing the web tier can do about this.</p>
+ </section>
+
+ <section name="Single Tier Applications -- Old Style">
+ <p>Much code that does not use EJBs is nevertheless written in the stateless-session-bean
+ style. When displaying a persistent object a backing bean method will open a
+ persistence-context, read the relevant objects into it and then close the context.
+ JSF components then render the object, but must be careful not to access any
+ relations that were not initialised before the context was closed. A later action
+ method which wants to save data will open a new context, reattach the object
+ retrieved earlier, flush the context to the database, then close the context again.</p>
+ <p>An alternative is to allow the object context to exist for the entire http request,
+ closing it only when the request is about to return (after render phase). This is
+ referred to as the "Open Session In View" pattern. In this way, the context is cached
+ (eg in a thread-local variable) for the duration of the request, and any JSF action
+ method that wants to access persistent objects just retrieves that context and uses
+ it. This is an extremely useful pattern, with no known drawbacks.</p>
+ <p>However with "Open Session In View" the context is still tied to just one request.
+ This still exposes the application to potential LazyInitialisationExceptions, as
+ follows:
+ <ul>
+ <li><p>request #1 loads an object from the database and stores it in the http session.
+ The page is nicely rendered, and no LazyInitialisationException can occur. The pool
+ is closed at the end of the request.</p></li>
+ <li><p>request #2 is executed, which tries to display more data from the object that
+ is cached in the session. That data is not currently loaded, however, and the
+ object is no longer in a context. An exception therefore occurs.</p></li>
+ </ul>
+ </p>
+ </section>
+
+ <section name="Single Tier Applications -- With Conversation Scoped Persistence">
+ <p>The solution to the problems described above is simply to store the PersistenceContext
+ object in the http session, and only close it after the conversation has ended, ie
+ when it has been decided to write to the database or abandon any changes made.</p>
+ <p>Although the default behaviour of JPA is to close the persistence context when a
+ transaction commits or rolls back, this is optional and simply disabling this allows
+ the persistence context to be cached over multiple requests. Instead, the db
+ connection associated with the persistence context is simply removed from the
+ context at the end of each request and returned to the connection pool. At the
+ start of the next request a different connection is retrieved from the db pool
+ and attached to the persistence context again.</p>
+ <p>Note that database transactions still occur; typically a transaction is started
+ on the context's connection at the beginning of each request and committed at the
+ end of each request. However as long as no flush() operation has been invoked on
+ the context, modifications made to objects in the context do not get written to
+ disk. Of course it is not possible for a real database transaction to be kept
+ open across requests, as that would require the database to keep rows in the
+ database locked for as long as the http session lasts (potentially hours), which
+ is simply unacceptable.</p>
+ <p>There are dangers to this approach; a persistence context can become large if
+ many objects have been loaded into it. Care needs to be taken to control the
+ amount of persistent data read/written during a conversation. Manual removal
+ of objects from the context which are no longer needed can be useful, or
+ secondary persistence contexts can be created to perform operations on objects
+ that are not needed to be kept in the conversation scope - particularly reads of
+ objects that will not be modified as part of the conversation.</p>
+ <p>There is also a potential problem when inserting new objects into the context
+ which have a database key that is generated via a database write. In this case,
+ the database write occurs in the request in which the object was added to the
+ context, even though the object's data does not get written until the end of
+ the conversation. If the conversation is "rolled back" then the key operation
+ remains, as that transaction has long since been committed.</p>
+ </section>
+
+ <section name="Handling Transactions">
+ <p>The scope of a persistence context and database transaction boundaries
+ (begin/commit) are separate issues. Multiple database transactions *can*
+ occur within the lifetime of a single persistence context. It isn't the
+ default - by default, close/rollback will close the associated context.
+ However it is possible to disable this default in which case the
+ persistence-context can last longer.</p>
+ </section>
+
+ <section name="How to Use Orchestra Conversation Scoped Persistence">
+ <p>When configured appropriately, Spring will automatically scan the beans
+ it loads for the standard persistence annotations, and injects a persistence
+ context where requested by the bean. Orchestra ensures that the persistence
+ context Spring injects is the appropriate one for the current conversation.</p>
+ <p>Your code is therefore simply straightforward:<pre>
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+public class ComponentDAO
+{
+ @PersistenceContext
+ private EntityManager entityManager;
+ ....
+}
+ </pre></p>
+ <p>Spring's annotation support does require, however, that the class containing
+ the annotation be declared as a Spring bean, and instantiated via Spring. This
+ means that all code which uses an instance of the above class needs to have it
+ injected, rather than using the new() operator to create the instance. Existing
+ code therefore may need to be restructured to take advantage of persistence
+ annotations with Orchestra. The persistence context object that Spring injects
+ is actually a proxy which looks up the correct EntityManager object to use
+ on each method call, so it is safe to use singleton scope (Spring's default
+ scope). Of course if the class has any other non-static members then the
+ scope should be set to "prototype", to avoid conflicts between different
+ instances of this class in different conversations.</p>
+ </section>
+
+ <section name="Documentation Still TODO">
+ <p>TODO: document Orchestra's transaction support features</p>
+ <p>TODO: is the persistence-context serializable? Are all persistent objects
+ in the context always serializable?</p>
+ </section>
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/maven/src/site/xdoc/persistence.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: myfaces/orchestra/trunk/maven/src/site/xdoc/todo.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/maven/src/site/xdoc/todo.xml?rev=1326868&view=auto
==============================================================================
--- myfaces/orchestra/trunk/maven/src/site/xdoc/todo.xml (added)
+++ myfaces/orchestra/trunk/maven/src/site/xdoc/todo.xml Tue Apr 17 01:29:52 2012
@@ -0,0 +1,35 @@
+<?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">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+<document>
+ <properties>
+ <title>Apache MyFaces Orchestra - TODO</title>
+ </properties>
+
+ <body>
+ <section name="TODO">
+ <ul>
+ <li>...</li>
+ </ul>
+ </section>
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/maven/src/site/xdoc/todo.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: myfaces/orchestra/trunk/maven/src/site/xdoc/usage.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/maven/src/site/xdoc/usage.xml?rev=1326868&view=auto
==============================================================================
--- myfaces/orchestra/trunk/maven/src/site/xdoc/usage.xml (added)
+++ myfaces/orchestra/trunk/maven/src/site/xdoc/usage.xml Tue Apr 17 01:29:52 2012
@@ -0,0 +1,263 @@
+<?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">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+
+<document>
+ <properties>
+ <title>Usage</title>
+ </properties>
+
+ <body>
+ <section name="Usage">
+ <p>
+ Once you have configured the system as described in
+ the installation document you can start using the new scope.
+ </p>
+
+ <p>
+ One more prerequisite: instead of configuring your beans in the faces-config.xml
+ configuration you have to do this in your spring configuration now. You can
+ take over all your beans into the Spring configuration, Spring also provides
+ a session and a request scope.
+ </p>
+
+ <p>
+ With this in place, we'll start evaluating the Orchestra-relevant use-cases now - so we'll
+ together look at what you will want to do with Orchestra.
+ </p>
+
+ <subsection name="Starting a conversation">
+ In the beginning, we'll want to start a conversation. Doing that is a no-brainer in Orchestra - if
+ you've declared the relevant managed beans as in the following example:
+<code><pre>
+<bean name="userInfo"
+ class="my.app.pck.backings.UserInfo"
+ scope="conversation.access"
+ autowire="byName"/>
+</bean>
+</pre></code>
+ <p>
+ We've learned about this syntax in the small example in the introduction - a short repetition:
+ <br/>
+ The scope-attribute of the bean-element will be defining the name of the scope; the
+ names can be whatever you like but we recommend "conversation.access" and "conversation.manual".
+ </p>
+ <p>The
+ <code>autowire="byName"</code>
+ Setting this property is fully optional. However, it
+ lowers the amount of configuration required. With this property set, Spring will scan your
+ bean configuration. Whenever it finds a bean with the same name as the property, it
+ will inject an instance of this bean configuration into this property.
+ </p>
+ <p>For example, if you configure a bean named
+ <code>userInfoDao</code>
+ and your bean has a
+ <code>setUserInfoDao()</code>
+ method Spring will inject an instance of this DAO into your bean.
+ </p>
+ <p>
+ Alternatively you could provide a custom conversation name:
+ </p>
+<code><pre>
+<bean name="bean1"
+ class="my.app.pck.backings.bean1"
+ scope="conversation.manual"
+ orchestra:conversationName="multibean"
+ autowire="byName"/>
+
+<bean name="bean2"
+ class="my.app.pck.backings.bean2"
+ scope="conversation.manual"
+ orchestra:conversationName="multibean"
+ autowire="byName"/>
+</pre></code>
+ <p>
+ As you can see in the above example we put two beans into the same conversation, which
+ means they share the same persistence context.<br />
+ This opens the possibility to keep the "one class per page" paradigm and still
+ allows you to pass entities between these two pages (e.g. Master/Detail scenarios).
+ </p>
+ </subsection>
+
+ <subsection name="Closing a conversation">
+ <p>
+ Closing a conversation is straightforward as well. If the bean is in a scope
+ that has been marked with lifetime=access then the conversation terminates
+ when a request is processed without referring to anything in that conversation.
+ If you've using a "manual" conversation instead, then you need to call:
+ <pre>
+ <code>Conversation.getCurrentInstance().invalidate()</code>
+ </pre>
+ from within the conversation-scoped bean. With this call, the conversation will cease to exist
+ and the bean will be cleared from the conversation.
+ </p>
+ </subsection>
+
+ <subsection name="Restart a conversation">
+ <p>
+ At times, you do not only want to close a conversation, but you also want to restart it
+ immediately. For this, use the following call:
+ <pre>
+public void invalidateAndRestart()
+{
+ YouBean bean = (YourBean)
+ ConversationUtils.invalidateAndRestart(Conversation.getCurrentInstance());
+ bean.setUser(createdUser.getId());
+}
+ </pre>
+
+ With the returned object, you can do configuration and initialization work.
+ </p>
+ </subsection>
+
+ <subsection name="Ensure a conversation is running">
+ <p>
+ If you have a conversation running over a multitude of pages,
+ you might want to check if the conversation has been initialized before you reach the page.
+ For doing this, you can call the method:
+
+ <code>ConversationUtils.ensureConversationRedirect(conversationName, redirectToJsp)</code>
+
+ before the conversation is first accessed on this page, as in an initialization or
+ prerender-method.
+ </p>
+ </subsection>
+
+ <subsection name="End a conversation by name">
+<code>ConversationUtils.invalidateIfExists(conversationName)</code>
+ </subsection>
+
+ <subsection name="JPA Transaction">
+ <b>Note</b>
+ :
+ Once again we would like to stress that Apache MyFaces Orchestra does not rely
+ on annotations, the JPA thing was just the one we build the examples with,
+ thats why we describe it at first.
+ <p>Every method in your conversation
+ bean is able to issue a database request or to call e.g. a DAO which will
+ do it. Its ensured that during the whole lifetime of this conversation
+ bean all database code will see the same entity manager.
+ </p>
+ <p>Methods
+ which change data has to be annotated with the
+ <code>@Transactional</code>
+ annotation.
+ </p>
+ <p>Which means, that every changed/inserted/deleted entity
+ will be flushed to the database and committed.
+ </p>
+ <p>Thats an important
+ thing to understand. You
+ <b>can</b>
+ change an entity whenever you want,
+ but it will only be flushed after such an annotated method has been
+ invoked.
+ </p>
+
+
+ </subsection>
+
+ <subsection name="Access a conversation">
+
+ <p>
+ From within a conversation scoped bean you can use
+
+ <code>Conversation.getCurrentInstance()</code>
+
+ or the ConversationManager API if you are outside of a conversation or would like to access another
+ conversation
+
+ <code>ConversationManager.getConversation(conversationName)</code>
+ </p>
+
+ </subsection>
+
+ <subsection name="Add beans to a conversation">
+ As e.g a http session or the request map, internally the conversation is also just a map
+ of beans.
+ <br/>
+ Using the spring configuration you're able to add just one bean, the conversation scoped
+ bean to the conversation with the same name as the bean.
+ <br/>
+ But there are ways to add other objects using the Conversation API.
+
+ <p>
+ Once you have access to the conversation object you can do:
+
+ <ul>
+ <li>conversation.setAttribute(key, value)</li>
+ <li>conversation.hasAttribute(key)</li>
+ <li>conversation.getAttribute(key)</li>
+ <li>conversation.removeAttribute(key)</li>
+ </ul>
+ </p>
+
+ <p>
+ Any bean implementing the <code>ConversationBindingListener</code> interface
+ will receive the <code>valueBound()/valueUnbound()</code>.
+
+ <ul>
+ <li>valueBound()<br/>
+ Will be invoked AFTER the bean has been added to the conversation map.
+ </li>
+
+ <li>valueUnbound()<br/>
+ Will be invoked AFTER the bean has been removed from the conversation map.<br/>
+ This will happen if you call <code>removeAttribute(key)</code> or if the
+ conversation ends, either manually or automatically due to a timeout.
+ </li>
+ </ul>
+
+ <b>Notice:</b> In <code>valueUnbound()</code> you can't assume that a faces context
+ will be available.
+ </p>
+ </subsection>
+
+ <subsection name="Using older Orchestra Releases">
+ <p>
+ The documentation above applies to the most recent Orchestra code. When using older
+ releases, the following information is useful.
+ </p>
+ <subsection name="Using aop:scoped-proxy">
+ <p>
+ For Orchestra 1.0, you should add an <code><aop:scoped-proxy /></code>
+ within the declaration of each bean that is of conversation scope. This ensures
+ that you will never have a reference to the real instance of your bean, but to
+ a proxy to it. There is no difference in the way how you work with this instance
+ in your code, but if you end a conversation and restart it, you'll appreciate the
+ difference: the proxy will make sure that your application will see the new instance.
+ </p>
+ <p>
+ This is automatically done for you with Orchestra 1.1 and later.
+ </p>
+ </subsection>
+ <subsection name="Flash Scope">
+ In version 1.0, the name "flash scope" was used for what is now called
+ "access scope". The two concepts are the same; when using orchestra 1.1
+ you must simply write "flash" wherever the more modern documentation
+ states "access". Orchestra 1.1 supports the old term for backwards
+ compatibility, so configuration files written for 1.0 should work fine
+ with release 1.1.
+ </subsection>
+ </subsection>
+ </section>
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/maven/src/site/xdoc/usage.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: myfaces/orchestra/trunk/maven/src/site/xdoc/viewController.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/maven/src/site/xdoc/viewController.xml?rev=1326868&view=auto
==============================================================================
--- myfaces/orchestra/trunk/maven/src/site/xdoc/viewController.xml (added)
+++ myfaces/orchestra/trunk/maven/src/site/xdoc/viewController.xml Tue Apr 17 01:29:52 2012
@@ -0,0 +1,210 @@
+<?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">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+<document>
+ <properties>
+ <title>ViewController</title>
+ </properties>
+
+ <body>
+ <section name="View Controller">
+ <p>
+ The ViewController is just a concept which binds a specific bean to a web-page.
+ In JSF this means, you have a managed bean associated with each view.
+ Note however that the ViewController is not limited to JSF; any framework can take
+ advantage of it to cause lifecycle method callbacks to occur for each page.
+ </p>
+ <p>
+ Using the Orchestra ViewController gives some very convenenient facilities.
+ </p>
+ <p>
+ Methods in your code can be invoke when the following events occur:
+ <ul>
+ <li>initView
+ <br />
+ This event will be fired after the JSF <code>RESTORE_VIEW</code> phase.
+ </li>
+ <li>preProcess
+ <br />
+ This event will be fired before the JSF <code>INVOKE_APPLICATION</code> phase.
+ </li>
+ <li>preRenderView
+ <br />
+ This event will be fired before the JSF <code>PRE_RENDER</code> phase.
+ </li>
+ </ul>
+ </p>
+ <p>
+ The ViewController concept is also the base for the core15 annotation
+ <code>@ConversationRequire</code> which allows you to issue a redirect if a
+ conversation times-out during a wizard-style pageflow.
+ </p>
+ <p>
+ Your view controller bean (the object on which callback methods are invoked) must
+ be configured as a managed bean (eg as a Spring bean).
+ </p>
+
+ <subsection name="Installation">
+ <p>
+ There are several parts to managing ViewControllers; the ViewControllerManager handles
+ the following tasks:
+ <ul>
+ <li>Choosing which object to invoke methods on (ViewControllerNameMapper)</li>
+ <li>Choosing which methods to invoke (ViewControllerExecutor)</li>
+ <li>Choosing when to invoke them</li>
+ </ul>
+ </p>
+ <p>
+ In a JSF environment, the default ViewControllerManager is set up with behaviour that
+ should suit most users. However this can be customised if the defaults do not suit.
+ See the javadoc documentation for the ViewControllerManager and related classes
+ for details on how to customise configuration.
+ </p>
+ </subsection>
+
+ <subsection name="ViewControllerNameMapper">
+ <p>
+ The default ViewControllerNameMapper maps a viewId to a bean-name as follows:
+ <ul>
+ <li>Convert each character after a "/" to upper-case</li>
+ <li>Remove any occurence of the "/" character</li>
+ <li>Stop at the first "." character and remove the rest</li>
+ <li>Prefix with a "_" character if the result is a reserved word or an invalid bean name</li>
+ </ul>
+ Examples:
+ <table>
+ <tr>
+ <th>View-Id</th>
+ <th>Bean name</th>
+ </tr>
+ <tr>
+ <td>mainform.jsp</td>
+ <td>mainform</td>
+ </tr>
+ <tr>
+ <td>userData/password.jsp</td>
+ <td>userDataPassword</td>
+ </tr>
+ <tr>
+ <td>requestScope.jsp</td>
+ <td>_requestScope</td>
+ </tr>
+ <tr>
+ <td>123set.jsp</td>
+ <td>_123set</td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ If no bean exists with a name that matches the computed bean-name, then no lifecycle
+ events are invoked for that view.
+ </p>
+ <p>
+ When the Orchestra core15 module is in the classpath, then annotations can also
+ be used to specify that a bean is a ViewController for a specific view. See the
+ section on the AnnotationsViewControllerNameMapper for details.
+ </p>
+ </subsection>
+
+ <subsection name="ViewControllerExecutor">
+ <p>
+ The default ViewControllerExecutor is a CompositeViewControllerExecutor which combines
+ the functionality of the following classes:
+ <ul>
+ <li>ReflectiveViewControllerExecutor (default)
+ <br />
+ The <code>ReflectiveViewControllerExecutor</code> uses reflection to lookup the
+ following public methods: initView, preRenderView, preProcess. <br />
+ All of the methods are optional.
+ </li>
+ <li>InterfaceViewControllerExecutor
+ <br />
+ The <code>InterfaceViewControllerExecutor</code> requires you to implement the
+ <code>org.apache.myfaces.orchestra.viewController.ViewController</code> interface.
+ </li>
+ </ul>
+ </p>
+ <p>
+ When the Orchestra core15 module is in the classpath, then annotations can also
+ be used to specify which methods on a bean should be invoked to handle lifecycle
+ events. See the section on the AnnotationsViewControllerExecutor for details.
+ </p>
+ </subsection>
+
+ <subsection name="AnnotationsViewControllerNameMapper">
+ <p>
+ To work with the <code>AnnotationsViewController</code> you have to use the core15
+ module. Once you added the jar to your classpath and configured the
+ <a href="installation.html">required import</a> statement
+ in your configuration file you are done.
+ </p>
+ <p>
+ The biggest advantage of <code>AnnotationsViewControllerNameMapper</code> is that you
+ do not have to follow any bean-naming scheme. Just annotate your managed-bean with the
+ <code>@ViewController</code> annotation.
+ </p>
+ <p>
+ Example:
+ <pre>
+@ViewController(
+ viewIds={"/annotations/Page1.jsp", "/annotations/Page2.jsp", "/annotations/Page3.jsp"})
+public class MultiViewController
+ </pre>
+ </p>
+ <p>
+ This configuration means that the class <code>MultiViewController</code> is responsible
+ for the three configured pages and will receive the lifecycle method callbacks.
+ </p>
+ </subsection>
+
+ <subsection name="AnnotationsViewControllerExecutor">
+ <p>
+ The <code>AnnotationsViewControllerExecutor</code> allows the methods to be
+ invoked to be marked via annotations. The methods can then have any name, and
+ the bean on which they exist does not need to implement any specific interface.
+ This is a feature of the core15 module, and is automatically enabled if the
+ Orchestra core15 library is in the classpath.
+ </p>
+ <p>
+ The available annotations are:
+ <ul>
+ <li>@InitView</li>
+ <li>@PreProcess</li>
+ <li>@PreRenderView</li>
+ </ul>
+ </p>
+ </subsection>
+
+ <subsection name="Comparison with the Apache Shale ViewController">
+ <p>
+ The ViewController concept in Orchestra was inspired by the Apache Shale ViewController,
+ and is very similar. Unfortunately the Shale version could not be used directly in
+ Orchestra; it is hoped that at some time in the future the two implementations can
+ be unified in some manner.
+ </p>
+ <p>
+ The Orchestra implementation currently lacks the ability for f:subview pages to have
+ their own view-controller.
+ </p>
+ </subsection>
+ </section>
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/maven/src/site/xdoc/viewController.xml
------------------------------------------------------------------------------
svn:eol-style = native