users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] [jsr344-experts] [1142-ResourceLibraryContracts] config options: property name, time and location (was: [971-MultiTemplate])

From: Edward Burns <edward.burns_at_oracle.com>
Date: Fri, 9 Nov 2012 14:11:48 -0800

Hello Volunteers,

This email resolves the name of the property for storing the resource
library contracts, and when and where the value of that property is set.
I will atomically send a separate mail regarding *how* the value of the
property is calculated, and yet another email regarding how the property
is *used*.

>>>>> On Tue, 6 Nov 2012 20:25:16 -0500, Leonardo Uribe <lu4242_at_gmail.com> said:

EB> Both of these answer the question, "How does a Page Author indicate
EB> that their pages should be influenced by a multi-template?"

EB> Frank's original reduced scope idea was to have a property on the
EB> FacesContext. We could keep that idea and make the property be able to
EB> return a list of resource contracts. Frank's idea, call it
EB> multi-template-zero-config for discussion, was for the spec to say
EB> nothing about how this property was to be set. In practice, he felt
EB> that people could decorate the FacesContextFactory to set it.

EB> Is that acceptable?

LU> Isn't it better to use an EL expression bound to a bean than override
LU> FacesContext?

Leo, let's just put this approach aside if you can agree with what I'm
proposing in this email. Search for CONDITIONALLY_RESOLVED:.

LU> The problem is, conceptually speaking, FacesContext has
LU> "request scope" , but this is a "view scope" value.

[...]

FC> I think the FacesContext can represent any scope, because it has any
FC> information it needs to decide about the prefixes:

[...]

LU> In my understanding, FacesContext is a "helper" object, more than an
LU> object that represent a scope. That does not change the relationship
LU> between the view, and the multi-template configuration. Take a look
LU> at JSF 2.2 spec section 7.7.2.1 ViewDeclarationLanguage.createView()
LU> :

LU> "... The createView() method must fulfill the following responsibilities.

LU> All implementations must:

LU> If there is an existing UIViewRoot available on the FacesContext, this method
LU> must copy its locale and renderKitId to this new view root. If not, this method

[...]

LU> In the case of multi-template configuration, the same step as with
LU> locale or renderKitId should be done: calculate it and store the
LU> values in the view. The multi-template configuration must be saved
LU> and restored with the view information. This ensures the view will
LU> be restored properly, because the calculation step is done when the
LU> view is built by first time.

I really like this idea.

FC> Ok. But we must expose it somehow so that the resource handler can
FC> pick it up. That's why I wanted it on the FacesContext.

I understand that is the most important quality of the property: the
resource handler can pick it up.

LU> I have been working for a long time on Partial State Saving algorithm,
LU> and something that I discover doing a lot of tests was that to ensure the state
LU> works correctly, it is absolutely necessary when restore the view to build the
LU> view in the same way it was built by first time.

I too have worked on and seen others work on this sort of thing. Leo, I
trust your instincts here.

CONDITIONALLY_RESOLVED: The name of the property is
resourceLibraryContracts. I considered resourceContracts but really the
feature is a library contract, not just a resource contract.

CONDITIONALLY_RESOLVED: Define a read-only property located on
UIViewRoot whose type is List<String>. Specify that if it is not set,
it must return an empty List. This property is accessible by doing
FacesContext.getViewRoot().getResourceLibraryContracts().

LU> In few words, the multi-template configuration is a parameter of the view.

I agree. Rather than introduce a new property on FacesContext, it is a
new property on the UIViewRoot. Let's introduce a new method
calculateResourceLibraryContracts(). Where should this method live?
The other calculate*() methods live on ViewHandler. Our new
calculateResourceLibraryContracts() is specific to the VDL, so it should
live on the VDL. Note that we lose the ability to define the contracts
on the <f:view> in this way because we will not have even loaded the XML
file that gives us the Facelet. I am fine with this loss.

CONDITIONALLY_RESOLVED: Add new method on VDL,
calculateResourceLibraryContracts(). This email doesn't say what this
method does other than returning List<String> of the resource contracts.

LU> Consider a view that has a multi-template contract implementation
LU> applied and you change the implementation in a POST. The view
LU> becomes unstable and that will lead to exceptions. The same happens
LU> when you change the locale and you use a localized composite
LU> component, or when you change the renderkit (because components
LU> added using @ResourceDependency annotation depends on the renderer
LU> classes).

We must disallow changing the value of contract property during request
processing. This is achieved by the property being read-only.

FC> We should simply enforce that FacesContext.getResourceContracts()
FC> returns the same result once it's calculated.

Yes, exactly, it's a read-only property.

CONDITIONALLY_RESOLVED: Modify 7.7.2.1 createView() to require calling
VDL.calculateResourceLibraryContracts() so that the read-only
resourceLibraryContracts property is correctly set when the UIViewRoot is
returned from that method. As I said above, the impl of
calculateResourceLibraryContracts() is in another email. How you set the
property on UIViewRoot before returning it from createView() is an
implementation detail.

ACTION: Please reply by 17:00 GMT Tuesday 20121113, earlier if you can manage!

Thanks,

Ed