You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2007/05/23 23:19:22 UTC

svn commit: r541091 - in /myfaces/current/orchestra/core/src/site/xdoc: bestPractice.xml component-bindings.xml

Author: werpu
Date: Wed May 23 14:19:22 2007
New Revision: 541091

URL: http://svn.apache.org/viewvc?view=rev&rev=541091
Log:
fixed a few things added a chapter regarding the component bindings...

Added:
    myfaces/current/orchestra/core/src/site/xdoc/component-bindings.xml
Modified:
    myfaces/current/orchestra/core/src/site/xdoc/bestPractice.xml

Modified: myfaces/current/orchestra/core/src/site/xdoc/bestPractice.xml
URL: http://svn.apache.org/viewvc/myfaces/current/orchestra/core/src/site/xdoc/bestPractice.xml?view=diff&rev=541091&r1=541090&r2=541091
==============================================================================
--- myfaces/current/orchestra/core/src/site/xdoc/bestPractice.xml (original)
+++ myfaces/current/orchestra/core/src/site/xdoc/bestPractice.xml Wed May 23 14:19:22 2007
@@ -1,112 +1,120 @@
-<?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">
-<document>
-	<properties>
-		<title>Best Practice</title>
-	</properties>
-
-	<body>
-		<section name="Best Practice">
-
-			Here we will collect what we think is the best practice to use all this stuff.
-			<br/>
-			However, you are not bound to it.
-
-			<li>
-				<ul>Have a single bean for your page.<br />
-					Means, you CAN use more than one, e.g if you
-					have to fill your layout with data it wouldn't make much sense to put this into each
-					backing bean.<br/>
-					However, taking this approach you enable some additional features the ViewController
-					stuff will provide.
-				</ul>
-			</li>
-
-			<subsection name="Single Page Conversation">
-
-				<p>
-					Single Page conversation are easy, just put the bean into the conversation scope und use
-					it in your value-/methodbinding.
-				</p>
-
-				<p>
-					Mostly on save actions end the conversation and maybe restart it to review the data.
-				</p>
-
-				<p>
-					Maybe also provide a way to cancel the current work, which will simply end the conversation.
-					(without commit to the database)
-				</p>
-
-			</subsection>
-
-			<subsection name="Multi Page Conversation">
-
-				<p>
-					For mutli page conversations you have to break through the first suggestion ;-), means,
-					its not possible to have the conversation bean the same name than the pages, a bean
-					can just have a single name.
-				</p>
-
-				<p>
-					And this is not that bad, the suggestion is to use a simple request scoped bean per page
-					and a single conversation scoped data.<br />
-					If you have three pages, e.g. startPage.jsp, enterPage.jsp, endPage.jsp you'll end up
-					with a structure like (note: the names are suggestions only):
-
-					<ul>
-						<li>Page:startPage.jsp</li>
-						<li>Page:enterPage.jsp<br/>Bean name: enterPage</li>
-						<li>Page:endPage.jsp<br/>Bean name: endPage</li>
-						<li>Conversation name: pagesData</li>
-					</ul>
-				</p>
-
-				<p>
-				You see, there is no bean required for the startPage. We also require the enterPage and endPage
-				to check if the conversation is really running.
-				</p>
-
-				<p>
-					We have to ensure that the user starts with the startPage. Reasons why this could be violated are:
-					<ul>
-						<li>the conversation timed out in the mid of the work</li>
-						<li>the user tampered the url</li>
-					</ul>
-				</p>
-
-				<p>
-					Now that we have a mini backing bean for the enterPage and the endPage we can put in code
-					to ensure it. We can ensure a conversation has been started, else issue a redirect
-					or JSF navigation.
-				</p>
-
-				<p>
-					Simply add a method called <code>initView()</code> to the enterPage and endPage bean like the
-					following:
-					<pre>
-public void initView()
-{
-    ConversationUtils.ensureConversationRedirect("pagesData", "/startPage.faces");
-}
-					</pre>
-
-					<b>Notice:</b> There is also a <code>JsfConversationUtils</code> class which allows you to invoke a navigation.<br/>
-					<b>Notice:</b> See the ViewController documentation how to use other strategies or adjust the mapping
-					fo the viewId to your bean names.
-				</p>
-
-				<p>
-					Once the core code has settled we will work out a method how to make this more
-					developer friendly, though, for a nice solution it looks like we can't
-					avoid the introduction of an annotation based solution.<br/>
-					Fully optional then, available when you add the core15 module.
-				</p>
-
-
-			</subsection>
-
-		</section>
-	</body>
+<?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">
+<document>
+	<properties>
+		<title>Best Practice</title>
+	</properties>
+
+	<body>
+		<section name="Best Practice">
+
+			This page should give some guidance to some best practices
+			we think should be applied to reach the fastest result.
+			
+			
+			<br/>
+			Feel free to adopt them, feel free to ignore them.
+			
+				<p>
+				In various tests and implementations it became clear very early  that the best approach 
+				is, to have a single page controller under one conversation for one or many pages
+				depending on your scope flow.
+				</p>
+				<p>
+				The reason for this self imposed limitation is that if you end up with too many conversations
+				things become complicated and if you use the conversations on a non page controller level, you will
+				lose some functionality the internal view handler mechanisms of orchestra expose to your bean.
+				</p>
+				<p>
+				Note, that all beans under one page controller are under the same conversation, unless they
+				already are under a different conversation scope when assigned!
+				</p>
+
+			<subsection name="Single Page Conversation">
+
+				<p>
+					Single Page conversations are easy, just put the bean, representing your view controller, into the conversation scope und use
+					it in your value-/methodbinding. 
+				</p>
+
+				<p>
+					Mostly on save actions end the conversation and maybe restart it to review the data.
+				</p>
+
+				<p>
+					Maybe also provide a way to cancel the current work, which will simply end the conversation.
+					(without commit to the database)
+				</p>
+
+			</subsection>
+
+			<subsection name="Multi Page Conversation">
+
+				<p>
+					For multi page conversations you have to break through the first suggestion ;-), means,
+					its not possible to have the conversation bean the same name than the pages, a bean
+					can just have a single name.
+				</p>
+
+				<p>
+					And this is not that bad, the suggestion is to use a simple request scoped bean per page
+					and a single conversation scoped data.<br />
+					If you have three pages, e.g. startPage.jsp, enterPage.jsp, endPage.jsp you'll end up
+					with a structure like (note: the names are suggestions only):
+
+					<ul>
+						<li>Page:startPage.jsp</li>
+						<li>Page:enterPage.jsp<br/>Bean name: enterPage</li>
+						<li>Page:endPage.jsp<br/>Bean name: endPage</li>
+						<li>Conversation name: pagesData</li>
+					</ul>
+				</p>
+
+				<p>
+				You see, there is no bean required for the startPage. We also require the enterPage and endPage
+				to check if the conversation is really running.
+				</p>
+
+				<p>
+					We have to ensure that the user starts with the startPage. Reasons why this could be violated are:
+					<ul>
+						<li>the conversation timed out in the mid of the work</li>
+						<li>the user tampered the url</li>
+					</ul>
+				</p>
+
+				<p>
+					Now that we have a mini backing bean for the enterPage and the endPage we can put in code
+					to ensure it. We can ensure a conversation has been started, else issue a redirect
+					or JSF navigation.
+				</p>
+
+				<p>
+					Simply add a method called <code>initView()</code> to the enterPage and endPage bean like the
+					following:
+					<pre>
+public void initView()
+{
+    ConversationUtils.ensureConversationRedirect("pagesData", "/startPage.faces");
+}
+					</pre>
+
+					<b>Notice:</b> There is also a <code>JsfConversationUtils</code> class which allows you to invoke a navigation.<br/>
+					<b>Notice:</b> See the ViewController documentation how to use other strategies or adjust the mapping
+					fo the viewId to your bean names.
+				</p>
+
+				<p>
+					Once the core code has settled we will work out a method how to make this more
+					developer friendly, though, for a nice solution it looks like we can't
+					avoid the introduction of an annotation based solution.<br/>
+					Fully optional then, available when you add the core15 module.
+				</p>
+
+
+			</subsection>
+
+		</section>
+	</body>
 </document>

Added: myfaces/current/orchestra/core/src/site/xdoc/component-bindings.xml
URL: http://svn.apache.org/viewvc/myfaces/current/orchestra/core/src/site/xdoc/component-bindings.xml?view=auto&rev=541091
==============================================================================
--- myfaces/current/orchestra/core/src/site/xdoc/component-bindings.xml (added)
+++ myfaces/current/orchestra/core/src/site/xdoc/component-bindings.xml Wed May 23 14:19:22 2007
@@ -0,0 +1,81 @@
+<?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">
+<document>
+	<properties>
+		<title>Apache MyFaces Orchestra - Component Bingings</title>
+	</properties>
+
+	<body>
+		<section name="Component Bindings">
+			<subsection name="Introduction">
+				<subsubsection name="Basic discrepancy">
+				While the best pratice is to have a single page controller under conversation per page or 
+				for a full multi page flow, there is a discrepancy between the scope length needed for the conversation
+				and the scope length for associated component bindings.
+				</subsubsection>
+				
+			</subsection>
+			<subsection name="Problem">
+				The main problem is, component bindings in a backend bean require a scope lenth of request.
+				The cause is that the component tree is regenerated at every request. Longer component bindings
+				are a possible cause for internal id clashes etc...
+				<p> </p>
+				The main problems we now face are, we have a single page controller/model object which is associated
+				to the view. The page controller/model now is stateful, which is exactly as inded, however we need
+				component bindings in this bean and those are referenced by the view.
+				The bindings under normal circumstances inherit exactly the scope of the page controller.
+				<p> </p>
+				Therefore following construct automatically is bound to fail:
+				<pre>
+&lt;component binding="#{viewcontrollerbean.bindingattribute}" /&gt;					
+				</pre>
+				The problem here is that the viewcontroller bean has a scope of conversation, the bindingattribute, however, needs
+				a scope of request.
+				This at the first look is a problem impossible to solve.
+				At the second look, Spring itself provides the solution. Since every bean referenced by
+				the framework and the view layer is a Spring bean, we get the solution out of the magical
+				Spring box.
+			</subsection>				
+			<subsection name="Solution">
+				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>
+&lt;component binding="#{viewcontrollerbean.componentbindingmodel.bindingattribute}" /&gt;					
+				</pre>
+				The accessor path has slightly changed, we have introduced a second bean a model
+				bean which holds our component bindings.
+				<p> </p>
+				What happens on the spring configuration side is simply following:
+				
+				<pre>
+&lt;bean id="componentbindingmodel" scope="request" class="path.to.our.model.class"&gt;
+   &lt;aop:scoped-proxy /&gt;
+&lt;/bean&gt;
+
+&lt;bean id="viewcontrollerbean" scope="conversation" ...&gt;
+      &lt;property name="componentbindingmodel"
+            ref="componentbindingmodel" /&gt;
+
+&lt;/bean&gt;
+				</pre>	
+The associated component binding model class is simply a class which holds the components as attributes and its associated setter
+and getter methods.						
+		<p> </p>	
+		What happens at call stage: The viewcontrollerbean is instantiated under conversation scope, the proxy
+		object is generated and assigned dependin on its lazy binding stage. 
+		At the request end, the content of the componentbindingmodel bean is dropped and only the empty proxy
+		shell still is referenced.
+		At the next request which references parts of the componentbindingmodel object the content again is initialized
+		and can be accessed. This way it is possible to bind the request scoped component bindings to any long running scope
+		no matter being it our conversation scopes or session scopes!		
+		</subsection>
+		</section>
+	</body>
+</document>
\ No newline at end of file