You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by im...@apache.org on 2007/08/18 09:37:58 UTC

svn commit: r567243 - in /myfaces/orchestra/trunk: core/src/main/java/org/apache/myfaces/orchestra/viewController/ core/src/site/ core/src/site/xdoc/ core15/src/main/resources/META-INF/

Author: imario
Date: Sat Aug 18 00:37:57 2007
New Revision: 567243

URL: http://svn.apache.org/viewvc?view=rev&rev=567243
Log:
changed ViewController bean name, added first version of the ViewController documentation

Added:
    myfaces/orchestra/trunk/core/src/site/xdoc/viewController.xml
      - copied, changed from r567240, myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml
Modified:
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/viewController/ViewControllerManager.java
    myfaces/orchestra/trunk/core/src/site/site.xml
    myfaces/orchestra/trunk/core15/src/main/resources/META-INF/spring-orchestra-init.xml

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/viewController/ViewControllerManager.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/viewController/ViewControllerManager.java?view=diff&rev=567243&r1=567242&r2=567243
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/viewController/ViewControllerManager.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/viewController/ViewControllerManager.java Sat Aug 18 00:37:57 2007
@@ -34,7 +34,7 @@
  */
 public interface ViewControllerManager
 {
-	public final static String VIEW_CONTROLLER_MANAGER_NAME = ViewControllerManager.class.getName(); 
+	public final static String VIEW_CONTROLLER_MANAGER_NAME = ViewControllerManager.class.getName().replace('.', '$');
 
 	public Object getViewController(String viewId);
 

Modified: myfaces/orchestra/trunk/core/src/site/site.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/site.xml?view=diff&rev=567243&r1=567242&r2=567243
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/site.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/site.xml Sat Aug 18 00:37:57 2007
@@ -44,6 +44,7 @@
 			<item name="Introduction and Glossary" href="introduction.html"/>
 			<item name="Installation" href="installation.html"/>
 			<item name="Conversation API Usage" href="usage.html"/>
+			<item name="ViewController" href="viewController.html"/>
 			<item name="Best Practice" href="bestPractice.html"/>
 			<item name="TODO" href="todo.html"/>
 			<item name="FAQs" href="faqs.html"/>

Copied: myfaces/orchestra/trunk/core/src/site/xdoc/viewController.xml (from r567240, myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml)
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/viewController.xml?view=diff&rev=567243&p1=myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml&r1=567240&p2=myfaces/orchestra/trunk/core/src/site/xdoc/viewController.xml&r2=567243
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/bestPractice.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/viewController.xml Sat Aug 18 00:37:57 2007
@@ -3,122 +3,173 @@
 	"http://www.apache.org/dtd/xdoc.dtd">
 <document>
 	<properties>
-		<title>Best Practice</title>
+		<title>ViewController</title>
 	</properties>
 
 	<body>
-		<section name="Best Practice">
+		<section name="View Controller">
 
-			This page will provide you with guidance to best practices
-			in using Apache MyFaces Orchestra - generally, it's better to
-			adhere to these principles.
-
-			<subsection name="Single Page Conversation">
-
-				<p>
-					In many cases, it is the easiest approach to
-					provide a single managed bean per view.
-					Single Page conversations are easy - put the bean representing your view controller
-					into the conversation scope und use it in your value-/methodbinding.
-					Additionally, there is a module in Orchestra which will provide convenient functionality
-					en plus - for that, you need to set the managed-bean name to the page-name.
-					<b>Notice:</b> See the ViewController documentation on how to use other naming strategies and so to adjust the mapping
-					from the view-id to your bean names.
-				</p>
-
-				<p>
-					The conversation will be started when the bean is first accessed,
-					it's your job to end the conversation by calling
-					<code>Conversation.getCurrentInstance().invalidate()</code>. You'll do that mostly in save actions
-					after you have saved data to the database.
-					Eventually, you might want to restart the conversation to provide access to the data again.
-					<code>Object yourBackingBean = ConversationUtils.invalidateAndRestart(Conversation.getCurrentInstance())</code>
-				</p>
-
-				<p>
-					Often, the user will also be allowed to cancel the current work,
-					in which case Orchestra will simply close the conversation
-					(without commit to the database). For achieving this, simply call:
-					<code>Conversation.getCurrentInstance().invalidate()</code>
-					without having called any persistence-layer save-methods before.
-				</p>
-
-			</subsection>
-
-			<subsection name="Multi Page Conversation">
-
-				<p>
-					For multi page conversations you have to break through the first suggestion ;-) which means
-					that it is not possible to have a conversation bean with the same name as the multitude of pages,
-					a bean can of course have a single name only.
-				</p>
-
-				<p>
-					The solution for this is to use a simple request scoped bean per page
-					and a single conversation scoped controller.<br />
-					If you have three pages, e.g. startPage.jsp, enterPage.jsp, endPage.jsp you'll end up
-					with a structure like (note: the bean 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 bean name: pagesController</li>
-					</ul>
+			<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 configured which directly matches to a view-id.
+			</p>
+			<p>
+				If you follow this concept you'll gain some very comfortable things. They are:
+				<br />
+				Notifications:
+				<ul>
+					<li>initView
+					<br />
+						This event fill be fired after the JSF <code>RESTORE_VIEW</code> phase.
+					</li>
+					<li>preProcess
+					<br />
+						This event fill be fired before the JSF <code>INVOKE_APPLICATION</code> phase.
+					</li>
+					<li>preRender
+					<br />
+						This event fill be fired before the JSF <code>PRE_RENDER</code> phase.
+					</li>
+				</ul>
+				The ViewController concept is also the base for the core15 annotation
+				<code>@ConversationRequire</code> which allows you to issue a redirect if a
+				conversations timed-out in the mid of a e.g. wizzard style pageflow.
+			</p>
+
+			<subsection name="Installation">
+
+				<p>
+					In a JSF environment Orchestra already configures the JSF system in a way which allows
+					you to start using this concept.
+					This has been done by installing the PhaseListener
+					<code>org.apache.myfaces.orchestra.viewController.jsf.ViewControllerPhaseListener</code>.
+					<br/>
+					However, there is a way which allows you to adjust the configuration as required.
 				</p>
-
-				<p>
-				As you can see, there is no bean required for the startPage. We require the enterPage and endPage beans
-				to check if the conversation is really running.
-				</p>
-
 				<p>
-					We have to ensure that the user starts with the startPage. Reasons why this might be violated are:
+					To make the ViewController work you need to have two things:
 					<ul>
-						<li>the conversation timed out in the mid of the work</li>
-						<li>the user tampered with the url</li>
+						<li>A NameMapper (org.apache.myfaces.orchestra.viewController.ViewControllerNameMapper)
+							<br/>
+							The NameMapper is responsible to build a managed-bean name out of the view-id.
+						</li>
+						<li>An Executor (org.apache.myfaces.orchestra.viewController.AbstractViewControllerExecutor)
+							<br/>
+							The Executor finally will invoke some methods on this managed-bean then
+							(if there is a bean with the mapped name).
+						</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 a running conversation. If the conversation has not been started we issue a redirect
-					or execute the JSF navigation system.
-				</p>
-
-				<p>
-					To ensure a running conversation, simply add a method called <code>initView()</code>
-					to the enterPage and endPage bean which looks like the
-					following:
+					Both things will be used by the
+					<code>ViewControllerManager</code>. Now, if you are in need
+					of a custom name mapping scheme, just create jour own
+					<code>ViewControllerManager</code> by inheriting from the
+					<code>org.apache.myfaces.orchestra.viewController.AbstractViewControllerManager</code>
+					class. Two methods you have to implement allow you to provide custom implementations for the
+					<code>>NameMapper</code> and the <code>Executor</code>.
+					<br/>
+					Finally you have to configure your implementation by adding an bean definition with the name
+					<code>org$apache$myfaces$orchestra$viewController$ViewControllerManager</code>. For example:
 					<pre>
-public void initView()
-{
-    ConversationUtils.ensureConversationRedirect("pagesController", "/startPage.faces");
-}
-					</pre>
+&lt;bean
+    name="org$apache$myfaces$orchestra$viewController$ViewControllerManager"
+    class="your.package.YourViewController"
+    scope="singleton"&gt;
 
-					<b>Notice:</b> There is also a <code>JsfConversationUtils</code>-class which allows you to invoke a navigation.<br/>
+&lt;/bean&gt;
+					</pre>
 
 				</p>
 
-				<p>
-					TODO - prepare a method to make this more
-					developer friendly, implement this in Orchestra and document it here.
-					However, for a nice solution it looks like we can't
-					avoid the introduction of an annotation based solution
-					which will optionally be available if you add the core15 module.
-				</p>
+			</subsection>
 
+			<subsection name="DefaultViewControllerNameMapper">
+				There is a default NameMapper which will be used if you do not provide your own.
+				The mapping will be 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>
+			</subsection>
 
+			<subsection name="ViewControllerExecutor (AbstractViewControllerExecutor)">
+				The ViewControllerExecutor is responsible to invoke the notification methods on your
+				managed-bean.<br />
+				Currently the Orchestra standard provides the following methods:
+				<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>
+					<li>AnnotationsViewControllerExecutor (core15)
+					<br />
+						The <code>AnnotationsViewControllerExecutor</code> might be the most powerful one.
+						It allows you to configure a managed bean as view controller without following any
+						naming scheme. Not for the bean name nor for the method name.<br />
+						This is a feature of the core15 module.
+					</li>
+				</ul>
+				Again, you have to configure a custom <code>ViewControllerManager</code> if you
+				do not want the default <code>ReflectiveViewControllerExecutor</code>.<br />
 			</subsection>
 
-			<subsection name="Component bindings">
-				<p>
-				Read something about <a href="component-bindings.html">component binding and the scoping problem</a>.
-				</p>
-				<p>
-					This document is not related to Apache MyFaces Orchestra. It's a good reading for every JSF developer.
-				</p>
+			<subsection name="AnnotationsViewController">
+				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="intallation.html">required import</a> statement
+				in your configuration file you are done.
+				<br />
+				The biggest advantage the <code>AnnotationsViewController</code> provides is, that you do
+				not have to follow any naming scheme. Just annotate your managed-bean with the
+				<code>@ViewController</code> annotation.
+				<br />
+				Example:
+				<pre>
+@ViewController(
+	viewIds={"/annotations/Page1.jsp", "/annotations/Page2.jsp", "/annotations/Page3.jsp"})
+public class MultiViewController
+{
+				</pre>
+				Which means the class <code>MultiViewController</code> is responsible for the three
+				configured pages and will receive the notification to the methods annotated with the
+				<ul>
+					<li>@InitView</li>
+					<li>@PreProcess</li>
+					<li>@PreRenderView</li>
+				</ul>
+				annotation.
 			</subsection>
 
 		</section>

Modified: myfaces/orchestra/trunk/core15/src/main/resources/META-INF/spring-orchestra-init.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core15/src/main/resources/META-INF/spring-orchestra-init.xml?view=diff&rev=567243&r1=567242&r2=567243
==============================================================================
--- myfaces/orchestra/trunk/core15/src/main/resources/META-INF/spring-orchestra-init.xml (original)
+++ myfaces/orchestra/trunk/core15/src/main/resources/META-INF/spring-orchestra-init.xml Sat Aug 18 00:37:57 2007
@@ -41,7 +41,7 @@
 	</bean>
 
 	<bean
-		name="org.apache.myfaces.orchestra.viewController.ViewControllerManager"
+		name="org$apache$myfaces$orchestra$viewController$ViewControllerManager"
 		class="org.apache.myfaces.orchestra.viewController.AnnotationsViewControllerManager"
 		init-method="initManager"
 		scope="singleton">