myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Myfaces Wiki] Update of "StudyGuide" by SimonKitching
Date Thu, 10 Nov 2005 23:56:47 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Myfaces Wiki" for change notification.

The following page has been changed by SimonKitching:
http://wiki.apache.org/myfaces/StudyGuide

New page:
When learning JSF, there's nothing quite like looking at a real implementation.

Here's a suggested list of classes/methods to look at when trying to get to grips with how
JSF and !MyFaces actually works,
together with a brief description of the typical behaviour of interesting methods.

Note that the descriptions below describe *typical* behaviour of the code. There are all sorts
of overrides,
configurable behaviours and special cases that can occur; see the real implementation for
the full details - or read
the O'Reilly book which takes 570 pages to describe this process :-)

javax.faces.webapp.!FacesServlet
  * method init shows basic faces setup. In particular it shows how the !FactoryFinder is
used to create the !LifeCycle and !FacesContext factories.
  * method service shows that the Lifecycle object controls most of JSF processing

org.apache.myfaces.lifecycle.!LifecycleImpl:
  * every method in this class is worth reading carefully.
  * the execute method is the core of JSF, and shows how the different phases fit together
  * the normal restoreView implementation recreates a tree of "empty" component objects using
type names it stored away earlier, calling the default constructor for each component type
to create the instances. Each created component's restoreState method is then called to reinitialise
the component's fields from the previously saved state data.
  * applyRequestValues calls getRenderer() on each component, then invokes the renderer's
decode method which gets a "client id" from the component and looks for a matching key in
the request params. If found, the component's _submittedValue member is set to the value found.
  * processValidations causes each "editable" component to execute any validators attached
to it, passing the _submittedValue value. If validation fails, a message is inserted into
a request-scope set of messages, and the "renderResponse" flag is set so that the following
updateModelValues and invokeApplication phases are skipped.
  * assuming no validation problems occurred, updateModelValues causes each component to copy
_submittedValue into whatever backing-bean property was bound to it using "#{bean.prop}" syntax.
The _submittedValue field is then set to null to indicate that the model was updated.
  * invokeApplication executes callbacks for any value-change or similar events discovered
and queued during earlier phases.
  * render iterates over each component, calling its getRenderer() method to get the renderer
object, then calling that renderer object to generate the appropriate output (HTML or other).
If a component has a _submittedValue, then that is rendered in preference to anything else.
This allows components which failed validation to re-render an invalid value entered by the
user.

javax.faces.component.UI!ViewRoot:
  * queueEvent is the method that is called when a component decides to fire a value-change
event (or any other type of event). Some interesting places where events are queued are:
    * javax.faces.component.UIInput, method validate
    * org.apache.myfaces.renderkit.html.!HtmlButtonRendererBase, method decode

javax.faces.component.UI!ComponentBase:
  * Method getRenderer shows how the renderkit-id from the current view, the component's declared
component-family and the component's declared renderer-type name are used to determine what
renderer object to use. 

org.apache.myfaces.renderkit.html.!HtmlRenderKitImpl:
  * getRenderer shows how a renderkit instance uses the component's component-family and renderer-type
to look up a map to determine the renderer class to be used for that component. Note also
that only one instance of each specific renderer class is ever created; a renderer instance
is expected to be stateless (and threadsafe) and is used to render all instances of the associated
components. The renderkit's map is configured in code for the built-in types, and any META-INF/faces.config
files found in the classpath can add extra entries to the map for a specific renderkit via:
{{{
      <render-kit>
       <render-kit-id>some-id</render-kit-id>
       <renderer>
        <component-family>javax.faces.Input</component-family>
        <renderer-type>org.apache.myfaces.InputSuggest</renderer-type>
        <renderer-class>org.apache.myfaces.custom.suggest.InputSuggestRenderer</renderer-class>
       </renderer>
}}}

javax.faces.webapp.UI!ComponentTag:
  * Method createComponentInstance shows how a UIComponent is instantiated if a JSP tag references
it and it doesn't already exist in the view, by calling Application.createComponent(String).
Note that createComponentInstance calls method getComponentType() on itself, which is typically
implemented in the leaf JSP tag classes, eg org.apache.myfaces.taglib.html.!HtmlCommandButtonTag.

org.apache.myfaces.application.!ApplicationImpl:
  * Method createComponent takes a String component-type, and looks up its component map to
find a Class object then calls class.newInstance on it. The component map is configured in
code for the built-in types, and any META-INF/faces-config.xml files found in the classpath
can add extra entries to this via:
{{{
        <component-type>...
        <component-class>...
}}}
  * The other methods of this class are worth studying for more advanced purposes; this is
where a lot of JSF customisation can occur.
    

Mime
View raw message