You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2008/02/21 14:46:07 UTC
svn commit: r629780 - in /myfaces/orchestra/trunk/core/src/site: site.xml
xdoc/implementation.xml xdoc/introduction.xml
Author: skitching
Date: Thu Feb 21 05:46:06 2008
New Revision: 629780
URL: http://svn.apache.org/viewvc?rev=629780&view=rev
Log:
Add implementation section.
Added:
myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml (with props)
Modified:
myfaces/orchestra/trunk/core/src/site/site.xml
myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml
Modified: myfaces/orchestra/trunk/core/src/site/site.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/site.xml?rev=629780&r1=629779&r2=629780&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/site.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/site.xml Thu Feb 21 05:46:06 2008
@@ -40,7 +40,7 @@
<item name="Introduction" href="introduction.html"/>
<item name="Conversations" href="conversation.html"/>
<item name="Persistence" href="persistence.html"/>
- <item name="Glossary" href="glossary.html"/>
+ <item name="Implementation" href="implementation.html"/>
<item name="Installation" href="installation.html"/>
<item name="Conversation API Usage" href="usage.html"/>
<item name="ViewController" href="viewController.html"/>
@@ -48,6 +48,7 @@
<item name="JSF Component Bindings" href="component-bindings.html"/>
<item name="TODO" href="todo.html"/>
<item name="FAQs" href="faqs.html"/>
+ <item name="Glossary" href="glossary.html"/>
</menu>
<menu ref="reports"/>
Added: myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml?rev=629780&view=auto
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml (added)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml Thu Feb 21 05:46:06 2008
@@ -0,0 +1,227 @@
+<?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 - Implementation Details</title>
+ </properties>
+
+ <body>
+ <section name="Overview">
+ <p>
+ To understand what features Orchestra can provide, and what its limitations are,
+ it can be helpful to understand how it works. This is entirely optional, and
+ you can skip this section if you wish.
+ </p>
+ <p>
+ Please note that the information in this section describes how the current
+ implementation works. This is subject to change in future releases.
+ </p>
+ </section>
+ <section name="Proxies">
+ <p>
+ Orchestra uses object "proxies" that intercept calls to real beans in order to
+ track data flows and to redirect them as appropriate.
+ </p>
+ <p>
+ When a bean is configured to live in an Orchestra scope, any time an instance
+ of that bean is created then what is returned is not a reference to the actual
+ type, but instead a proxy object. The proxy object is of the same type (ie
+ "x instanceof TheExpectedType" will return true). If you use getClass() on the
+ proxy object, it may show that the proxy is a subclass of the expected type
+ (depending on how the proxying is implemented). However in most cases this doesn't
+ matter; the proxy can be treated exactly as if it was of the expected type, and of
+ course provides all the same methods that the expected type supports.
+ </p>
+ <p>
+ Of course this relies upon instances being created in a way that Orchestra can
+ intercept in order to create the proxy object. The most common usage is expected
+ to be JSF with Spring; in this setup a custom JSF VariableResolver is automatically
+ registered so that EL expressions such as "#{myBean}" cause Spring to handle the
+ lookup, and Orchestra's Spring scope-handler will then automatically proxy the bean.
+ However other presentation-tier approaches (eg plain jsp or servlets) and other
+ bean-management implementations (such as Google Guice) should be usable with
+ Orchestra as long as there is a mechanism for the appropriate proxies to be
+ created when needed.
+ </p>
+ <p>
+ The proxy has two distinct functions: to direct calls to an appropriate "real"
+ underlying bean (similar to Spring's aop:scoped-proxy), and to run an arbitrary
+ set of "advices" around each method call on the proxy. In particular, an advice is
+ used to implement Orchestra's persistence support (see later).
+ </p>
+ </section>
+ <section name="Indirection">
+ <p>
+ The proxy object returned by orchestra during a bean lookup does not directly hold
+ a reference to the underlying bean. Instead it just keeps:
+ <ul>
+ <li>a reference to a Scope object</li>
+ <li>a conversation-name string</li>
+ <li>a bean-name string</li>
+ </ul>
+ </p>
+ <p>
+ Invoking any method on the proxy object causes it to:
+ <ul>
+ <li>fetch the ConversationManager object for the current user</li>
+ <li>fetch the current ConversationContext for the user's current window</li>
+ <li>fetch the correct Conversation instance (using the conversation-name)</li>
+ <li>
+ fetch the correct target object from the Conversation (using bean-name),
+ or (if the instance does not yet exist) create an instance and store it in the
+ conversation.
+ </li>
+ </ul>
+ Then the originally invoked method is forwarded to the target object that was found.
+ </p>
+ <p>
+ Any call on a method of the proxy will therefore be forwarded to an instance that is
+ stored in a specific Conversation object. If the Conversation object is deleted, then
+ invoking a method on the proxy will just create a new Conversation instance and a
+ new instance of the target bean. Because of this, proxy objects can be retained
+ for any length of time; they never point to "stale" objects. This in turn allows
+ Orchestra to discard conversation objects at appropriate times without breaking
+ code holding references to those objects.
+ </p>
+ <p>
+ There is of course a performance penalty for this; invoking a method on a
+ conversation-scoped object (via its proxy) require a couple of hashmap lookups to
+ locate the target object, plus whatever internal overhead the proxying library
+ (currently CGLIB) adds.
+ </p>
+ <p>
+ Note that in Orchestra Core 1.0 a spring aop:scoped-proxy tag was needed on bean
+ definitions in order to enable the above functionality. Orchestra does function
+ without the indirection feature, but code must then be careful not to store any such
+ references for later use; instead beans can only be referenced via EL expressions.
+ It was strongly recommended in Orchestra 1.0 that aop:scoped-proxy be added to
+ each conversation-scoped bean definition and it is now automatic in Orchestra
+ Core 1.1.
+ </p>
+ </section>
+ <section name="Storing Conversations">
+ <p>
+ Conversations are stored within a ConversationContext which is stored within a
+ ConversationManager which is in turn stored within an HttpSession.
+ </p>
+ <p>
+ A conversation and its associated data therefore lasts as long as the user's
+ session object, unless explicitly deleted by Orchestra.
+ </p>
+ </section>
+ <section name="Access Scope">
+ <p>
+ When a proxy is invoked, and retrieves a target bean from a specific conversation
+ it also marks the conversation as "accessed". This allows Orchestra to determine
+ whether a conversation is currently "in use", or whether the user has navigated off
+ to some other part of the webapp. When the conversation is marked as "access" scope,
+ and is not in use then it is simple to detect this and discard the conversation
+ (together with all the bean instances that are stored in it).
+ </p>
+ <p>
+ Because proxies simply trigger the creation of new instances (and a conversation to
+ hold it) when needed, a user returning to an "access scope" page simply causes a
+ "fresh" version of the page state to be created.
+ </p>
+ <p>
+ This approach is quite different from some other libraries that provide conversation
+ scope. In particular, it does not require any elaborate flow-control state charts
+ to control navigation. With Orchestra the detection of beans that are no longer in
+ use is completely automatic.
+ </p>
+ </section>
+ <section name="Manual Scope">
+ <p>
+ With manual scope, Conversation instances are only deleted when application code
+ makes an explicit call to the Orchestra API, or when a JSF tag in a page makes
+ that call. The application therefore itself determines when a set of beans
+ (ie a conversation) is no longer needed. The implementation of this is obvious:
+ a ConversationContext object holds a map of conversations by name, and this
+ just removes the appropriate (name, Conversation) entry from that map. All the
+ beans in the conversation then become elegible for garbage-collection. Note
+ that Orchestra provides an option for beans in a conversation to be notified
+ when the conversation is terminated, which provides a kind of "destructor"
+ opportunity.
+ </p>
+ </section>
+ <section name="Multiple beans in a single Scope">
+ <p>
+ Each conversation has a name. By default, a conversation-scoped bean will be
+ placed in a conversation whose name is the bean-name used to retrieve that bean
+ from the dependency-injection system (Spring or other). Therefore by default
+ each conversation has only one bean in it.
+ </p>
+ <p>
+ Configuring a group of beans to belong to the same conversation is quite
+ useful with both Access and Manual scopes. To do this, simply ensure that the
+ configuration on the bean declaration specifies a conversation name. The
+ Conversation object has a Map of the objects in it, and so therefore can
+ hold any number of different beans, keyed by their bean-name.
+ </p>
+ </section>
+ <section name="Multiple Window Support">
+ <p>
+ An http session is typically maintained via a "cookie" that identifies the session
+ to be used for each request. A web-browser can open multiple windows or tabs which
+ share the same cookies; in this situation requests from different windows will all
+ use the same http-session on the server, and therefore access exactly the same
+ instances of session-scoped objects.
+ </p>
+ <p>
+ Unfortunately reusing session-scoped objects for completely unrelated requests
+ coming from different windows or tabs of a user's browser can cause nasty problems.
+ </p>
+ <p>
+ The Java Servlet standard does not support more than one session per user. However
+ Orchestra effectively provides this by keeping conversation objects as children of
+ a ConversationContext object. All that is needed is for each window to specify a
+ different ConversationContext object to use. Further documentation on this feature
+ can be found elsewhere on the Orchestra site.
+ </p>
+ </section>
+ <section name="Persistence">
+ <p>
+ Each conversation can optionally have a PersistenceContext associated with it. When
+ this is configured, then after a proxy has been invoked and has determined which
+ conversation the target bean is in, it configures the PersistenceContext associated
+ with that conversation as "the global persistence context". Any persistence operations
+ performed by the target bean (or the ordinary instances it calls) therefore run in
+ the context of the persistence context for that conversation. When the method on the
+ target bean returns, the proxy restores the previous persistence context.
+ </p>
+ <p>
+ Conversation instances are stored (indirectly) in the user session, so the persistence
+ context objects last across multiple requests, and are only discarded when the associated
+ conversation object is discarded. This allows "long running" persistence operations.
+ </p>
+ <p>
+ As noted elsewhere, this is useful only in applications where the database access and
+ the web presentation logic exist in the same physical tier. This is common for
+ small to medium applications, but the largest and most security-sensitive applications
+ typically keep database access logic in a separate tier and therefore this Orchestra
+ feature cannot be applied. However there are many single-tier applications where this
+ functionality can save a lot of developer time and effort.
+ </p>
+ </section>
+ </body>
+</document>
Propchange: myfaces/orchestra/trunk/core/src/site/xdoc/implementation.xml
------------------------------------------------------------------------------
svn:eol-style = native
Modified: myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml?rev=629780&r1=629779&r2=629780&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml (original)
+++ myfaces/orchestra/trunk/core/src/site/xdoc/introduction.xml Thu Feb 21 05:46:06 2008
@@ -39,8 +39,18 @@
<p>Orchestra Core requires only Java 1.4 and JSF 1.1.</p>
</section>
<section name="Important Information">
- <p>At the current time, Orchestra is not safe for use with distributed sessions.
- If you need this feature, please contact the development list.</p>
+ <p>
+ At the current time, Orchestra is not safe for use with distributed sessions.
+ If you need this feature, please contact the development list.
+ </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>
</section>
</body>
</document>