users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] [jsr344-experts] [1055-StatelessJSF] RESOLVED

From: Edward Burns <edward.burns_at_oracle.com>
Date: Wed, 27 Feb 2013 20:52:38 -0800

>>>>> On Wed, 27 Feb 2013 10:15:55 -0500, Leonardo Uribe <lu4242_at_gmail.com> said:

LU> Hi
EB> I understand and acknowledge your concern. The main user-level
EB> documentation for this will be on the "transient" attribute on <f:view>.
EB> There I will place a prominent warning that this feature will not work
EB> with @ViewScoped managed beans.
EB>
EB> Is that sufficient to win at least your acquiescence, Leonardo?

LU> Yes, a warning is enough. The important is be clear about the consequences
LU> of use the attribute, to prevent people ask why this does not work over and
LU> over in the future.

KM> We also need to be clear about how this really helps. It's not a huge
KM> performance boost for request processing, but it could have a big
KM> effect on memory usage. And, in some cases, it makes development
KM> easier.

[...]

LU> - It will not have any impact over memory usage, because the view is
LU> built at every request. To get the lowest possible memory usage we
LU> need a view pool like the one proposed, that reuse views across
LU> request, but does not conflict with the GC using soft/weak
LU> references (already done).

I totally agree with this. As probably the last one still here who was
involved with the original design of StateManager, I can say that the
original designers had this in mind.

[...]

LU> But please go ahead with the "transient" attribute on f:view idea, because
LU> after all, the changes are minimal and can be done in no time.

I have just committed these spec changes. Manfred assures me the
corresponding implementation work can be done in time for our release on
Monday of Mojarra 2.2.0-m10 into the GlassFish 4.0 trunk.

It's not every day you get to close a JIRA issue with 47 votes.

M applicationIntegration.fm

- Make 7.7.2.8 ViewDeclarationLanguage.restoreView() be:

The JSP implementation must:

  If no viewId could be identified, return null.

  Call the restoreView() method of the associated StateManager, passing
  the FacesContext instance for the current request and the calculated
  viewId, and return the returned UIViewRoot, which may be null.

The Facelets implementation must:

  Call ResponseStateManager.isStateless(). If the result is false,
  proceed as specified in the JSP implementation. Otherwise, take the
  following steps and return.

  * Obtain a reference to the ViewDeclarationLanguage from the
  ViewDeclarationLanguageFactory. This is necessary to allow for proper
  decoration. It is not acceptable to simply use the java language this
  keyword.

  * Call createView() on the ViewDeclarationLanguage instance, passing the
  context and viewId arguments. Let viewRoot be the result.

  * Call FacesContext.setViewRoot(viewRoot).

  * Call buildView() on the ViewDeclarationLanguage, passing the context
  and viewRoot.

  Return the viewRoot.

- Add new section 7.8.1.1

  Version 2.2 of the specification adds support for stateless views. In
  such a view, the UIComponent state for the components is not
  saved. This feature must be used with full awareness of the
  statefulness requirements of the components in the view. If a
  component requires state to operate correctly, it must not be used in
  a stateless view. Furthermore, it is not required that @ViewScoped
  managed beans work at all with stateless views. This feature only
  works with Facelet based views, not JSP based views.

  To mark a view as stateless, the existing transient property from
  UIComponent is exposed to the view author by means of the transient
  attribute on the <f:view> tag from the Faces Core tag library. The
  following spec sections contain more normative requirements for
  stateless views.

  * The vdldocs for the Facelet variant of the <f:view> tag.

  * The javadocs for ResponseStateManager.writeState(FacesContext, Object)

  * The javadocs for ResponseStateManager.isStateless(FacesContext)
    Section 7.7.2.8 "ViewDeclarationLanguage.restoreView()"

  * The javadocs for javax.faces.view.ViewScoped

  * The javadocs for javax.faces.bean.ViewScoped

M jsf-api/src/main/java/javax/faces/view/ViewScoped.java
M jsf-api/src/main/java/javax/faces/bean/ViewScoped.java

- Additional requirement:

+ * <p>If <code>ProjectStage</code> is not
+ * <code>ProjectStage.Production</code>, verify that the current {_at_link
+ * javax.faces.component.UIViewRoot} does not have its {_at_code transient}
+ * property set to {_at_code true}. If so, add a <code>FacesMessage</code>
+ * for the current {_at_code viewId} to the <code>FacesContext</code>
+ * stating {_at_code @ViewScoped} beans cannot work if the view is marked
+ * as transient. If <code>ProjectStage</code> <strong>is</strong>
+ * <code>ProjectStage.Production</code>, do not do this
+ * verification.</p>

M jsf-ri/conf/share/facelets_jsf_core.tld

- Document the <f:view transient> attribute.

+ <![CDATA[<p class="changed_added_2_2">If
+ <code>true</code>, this view must not participate in
+ state saving or restoring. Note that transient views
+ may not be used with <code>@ViewScoped</code> managed
+ beans. The implementation must call
+ <code>setTransient()</code> on the
+ <code>UIViewRoot</code>, passing the value of the
+ attribute as specified in the markup.</p>]]>


M jsf-api/src/main/java/javax/faces/render/ResponseStateManager.java

- new method isStateless():

 + /**
 + * <p class="changed_added_2_2">If the preceding call to {_at_link #writeState(javax.faces.context.FacesContext, java.lang.Object)}
 + * was stateless, return {_at_code true}. If the preceding call to {_at_code writeState()} was
 + * stateful, return {_at_code false}. Otherwise throw {_at_code IllegalStateException}.</p>
 + *
 + * <div class="changed_added_2_2">
 + *
 + * <p>To preserve backward compatibility
 + * with custom implementations that may have extended from an earlier
 + * version of this class, an implementation is provided that returns
 + * <code>false</code>. A compliant implementation must override this
 + * method to take the specified action.</p>
 + *
 + * </div>
 + *
 + * @param context The {_at_link FacesContext} instance for the current request
 + * @throws NullPointerException if the argument {_at_code context} is {_at_code null}.
 + * @throws IllegalStateException if this method is invoked and the statefulness
 + * of the preceding call to {_at_link #writeState(javax.faces.context.FacesContext, java.lang.Object)}
 + * cannot be determined.
 + *
 + * @since 2.2
 + *
 + *
 + */
 +
 + public boolean isStateless(FacesContext context) {
 + return false;
 + }

- New requirements in writeState():

+ * <p class="changed_added_2_2">Call {_at_link FacesContext#getViewRoot()}.
+ * Call {_at_link javax.faces.component.UIComponent#isTransient()}
+ * returns {_at_code true}, take implementation specific action so that the
+ * following call to {_at_link #isStateless} returns {_at_code true} and return.
+ * Otherwise, proceed as follows.</p>

M preface.fm

- Add new big ticket feature, Stateless Views, with cross reference to
  overview section 7.8.1.1.

Sending jsf-api/src/main/java/javax/faces/bean/ViewScoped.java
Sending jsf-api/src/main/java/javax/faces/render/ResponseStateManager.java
Sending jsf-api/src/main/java/javax/faces/view/ViewScoped.java
Sending jsf-ri/conf/share/facelets_jsf_core.tld
Sending nbproject/project.xml
Transmitting file data .....
Committed revision 11666.

Ed