Search on blog

Petition by Java EE Guardians

Twitter

luni, 16 noiembrie 2015

JSF view metadata facet demystified

The JSF metadata are declared via view
metadata facet (lives in the view or in a template client).

The JSF view metadata facet is tied up to view parameters and view actions.

- view parameters used to set in
managed beans/preserve over views,
convert and validate the GET parameters (<f:viewParam>)

- view actions or performing business action on GET parameters (<f:viewAction> and <f:event>)

History

Now, the JSF
view is programmatically represented by the component root (UIViewRoot).
Some of the supported metadata includes locale, content type, encoding, render
kit, phase listeners, etc (all these are information needed by the current
view). Probably, you are used to see something like this:

Starting
with JSF 2.2 a view can support stateless feature, and this is indicated as:

<f:view transient="true">

...

</f:view>

But these
"per attribute" based metadata are pretty simple, while the goal of
supporting view parameters/actions implies complex metadata. But, <f:view>
cannot handle such complex metadata, so JSF 2.0 introduced the viewmetadata facet.

So, this
facet (by default, ignored in a UI component tree visit) is dedicated to the UIViewRoot
and its name is, javax_faces_metadata. Since the metadata facet can
contain UI components, it practically opens a new perspective on supporting
metadata. In addition, metadata are "decoupled" from view and
accessible on demand. The view metadata facet can be declared as any other JSF
facet, only that it lives in the <f:view> tag:

<f:view>

<f:facet
name="javax_faces_metadata">

...

</f:facet>

...

</f:view>

Beside the
"per attribute" based metadata , starting with JSF 2.0 more metadata
are supported. First, we have the view parameters that instructs JSF about how request parameters should be
handled when a view is either requested or linked (e.g. from bookmark). Beside
the view parameters, in the meta-model we have view actions. The story behind
view actions is pretty simple: view parameters cannot provide action invocation
and navigation, which implies lazy loading the data. JSF 2.0 fixes this issue
via <f:event>,
but this has several drawbacks (e.g. the pointed listener is invoke at each
request, it doesn't support navigations, etc), so starting with JSF 2.2, we
have view actions (<f:viewAction>).

Well, after
the view parameters have been added, the view metadata facet also gets a
shortcut for the above <f:facet> form. This is
<f:metadata> tag. So, now we write:

<f:view>

<f:metadata>

...

</f:metadata>

...

</f:view>

Or, even
without the optional <f:view>:

<f:metadata>

...

</f:metadata>

Code

The ViewMetadata
contract is defined in java.faces.view as an abstract class. Beside
its abstract methods, this class implements the methods for obtaining the
current view parameters/actions and a flag method that determines if the
provided UIViewRoot
has a view metadata facet with children.

Let's take a
look to the ViewMetadata#getViewParameters()
- check out the highlighted comments:

// this method return a
collection of view parameters associated with the passed root

Now, an
implementation (extension) of ViewMetadata must create the facet (createMetadataView())
and return the view ID (getViewId()) for it. Before we will talk
about the Mojarra implementation (com.sun.faces.application.view.ViewMetadataImpl)
let's point out the moment when the view metadata facet enters into scene.

For this, we
need to focus on the Restore View phase execution. This is the first phase in
JSF lifecycle, and when the current request is not postback, JSF will create
the view metadata facet via ViewMetadata#createMetadataView(). So, the
view metadata facet is created only once per view, at initial request! This is
not re-created on postbacks! The relevant code is:

Metadata is
just a way of configuring the view parameters and actions that should take
place before the view is rendered without user interaction. Think to a view
parameter which is basically a UIInput, only that it doesn't render a <input
type="text" value="..."/> and it is submitted
without the need for the user to press a button. In a rough manner, you can
think that the content of <f:metadata> is auto-submitted.
Normally, an user cannot submit a form until the view is ready. So, <f:metadata>
is perfect for initializing the current view (and executing actions) based on
information provided from previous views. Think that the <f:metadata>
gives to JSF the current view's metadata. Since this tag is about current view
metadata it doesn't participate in XHTML templates (the page author must ensure
that the <f:metadata>
element does not appear on a template or included page; it can be in a template
client) and it is direct child of <f:view>.

Abonaţi-vă la JSF/OmniFaces Fans

Visitors Starting 4 September 2015

Others

[OmniFaces utilities]

Renderers

Collection of utility methods for the JSF API with respect to working with Renderer

Platform

This class provides access to (Java EE 6) platform services from the view point of JSF

Map Wrapper

Implementation of Map that wraps another map. This allows interception of one or more method on this wrapped map

JNDI

Utility class for simplifying some web related tasks that use JNDI under the hood, such as getting the <env-entry> from web.xml

State

Helper class for StateHelper that uses generic type-inference to make code that uses the StateHelper slightly less verbose

Beans

Collection of utility methods for the CDI API that are mainly shortcuts for obtaining stuff from the BeanManager

Components

Collection of utility methods for the JSF API with respect to working with UIComponent. There are several traversal/lookup methods, there are several UIForm and UIInput related methods which makes it easier to deal with forms and inputs

.Events

Collection of utility methods for the JSF API with respect to working with system and phase events