users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] [jsr344-experts] Re: [1142-ResourceLibraryContracts] How the property is used (was: [971-MultiTemplate])

From: Edward Burns <edward.burns_at_oracle.com>
Date: Mon, 12 Nov 2012 18:21:53 -0800

>>>>> On Mon, 12 Nov 2012 20:50:55 +0100, Frank Caputo <frank_at_frankcaputo.de> said:

FC> Am 09.11.2012 um 23:11 schrieb Edward Burns <edward.burns_at_oracle.com>:

EB> CONDITIONALLY_RESOLVED: Any directory within contracts in the webapp
EB> root or within META-INF/contracts on the classpath is taken to be a
EB> resource library contract.

FC> Where do I put resources belonging to the contract? Under
FC> META-INF/contracts/foo/resources or
FC> META-INF/resources/contracts/foo?

I was thinking it would be

<root>contracts/foo

or

META-INF/contracts/foo

directly.

LU> Ok. Note that resources inside this folder probably should be handler
LU> in a similar
LU> way as resources inside META-INF/resources

Exactly.

EB> SECTION: Encoding Resource Library Contracts
EB>
EB> When encoding resources from a resource library contract so they can be
EB> served during resource requests, there is no need for the system to be
EB> aware of the fact that the resource is from a resource library contract.
EB> The existing Resource.getRequestPath() is sufficient.

FC> So getRequestPath() will include the contract prefix?

Ahh, good catch, yes. I had this in one revision, but it slipped out. We
have will have a new query param, "con=" that will be the contract id.

LU> I like the idea. Use a different folder has sense, because a resource library
LU> contract uses an "extended model" than the one for normal jsf resource
LU> libraries, but in some parts it has a similar behavior.

LU> But note find the available contracts can be an expensive
LU> operation. In JSF 2.0, the concept of library/resource versions was
LU> added, but because an implementation detail about jar files (it is
LU> not possible to scan a folder without read the whole jar file), it
LU> was necessary to disable that concept when used inside jar files
LU> (META-INF/resources).

Yes, we did have to avoid versions in jar files for that reason.

LU> Anyway, it is possible to scan for resource library contracts only at startup
LU> time. When a resource request path is resolved, this scan should be avoided.
LU> Probably, as an implementation detail in MyFaces it will be necessary to
LU> provide SPI interfaces to customize this detail, as it has been done previously
LU> in other similar cases.

Good.

[...]

EB> SECTION: changes to the FaceletCache

EB> Frank tried to explain this to me in a hangout we had, but I still
EB> struggle to understand how to articulate the change that must be made
EB> with respect to the FaceletCache. I think the resolution we reached was
EB> that we would have to have a FaceletCache instance for each contrac.
EB> Frank I need your help on this part for sure.

FC> The problem is that the facelets compiler puts the facelet
FC> (e.g. home.xhtml) and the template together. So we must ensure that
FC> we get 2 instances for 2 different contracts for the facelet. I
FC> solved this problem with a FaceletFactory for each prefix
FC> (contract). I'm not sure, if a FaceletCache instance for each
FC> contract is sufficient. We should asap start prototyping this to be
FC> sure.

LU> Now I get it. In theory, FaceletCache uses an URL to identify in a
LU> unique way a facelet, but this URL in practice is the one related to
LU> the physical resource to be served. So, it does not matter if there
LU> are two different contracts with the same facelet name, internally
LU> the resources are located in different places and the URL stored in
LU> FaceletCache will be always different.

LU> But there is another problem already mentioned related to how
LU> facelet resources are resolved, that needs to be fixed. In few
LU> words, if a template is in /dirA/a.xhtml and there is an entry like
LU> this:

LU> <ui:decorate template="b.xhtml"/>

LU> the related resource should be in /dirA/b.xhtml . Right now,
LU> facelets try to derive the path using the url of the facelet that
LU> has the reference. Instead, we should provide a way to resolve those
LU> scenarios in a clean way. That's the reason why we need
LU> createViewResource(). Once facelet has derived the alternate view
LU> resource location, it should call createViewResource() to get the
LU> Resource instance and get the right URL to use in FaceletCache.

LU> In that order of ideas, we only need one FaceletCache (with the fix
LU> over composite components).

What fix are you talking about?

LU> Is it possible to load/unload resource library contracts when the application
LU> is running? If it is not, one FaceletCache per app is enough, otherwise, it is
LU> necessary to define a "lifecycle" for facelet instances stored in
LU> the cache.

I think we can safely say that is not possible.

LU> I think we have discussed before the need of solve some issues related to
LU> FaceletCache. For example, in MyFaces there are 3 types of facelets
LU> (Mojarra has 2):

LU> - Normal Facelet :
LU> - View Metadata Facelet : Calculates metadata info about a view.
LU> - Composite Component Metadata Facelet : Calculates metadata info about
LU> a composite component.

LU> I strongly think FaceletCache needs to be updated to include the third type,
LU> even if Mojarra does not use it. But that's another history.

Please file an issue about that.

LU> What's important here is if the assumption that if it is possible to
LU> add and remove resource library contract on runtime.

I think we can safely say that it's not possible.

EB> ACTION: Can someone please verify that this is the only change I need to
EB> make to ResourceHandler? In other words, none of the createResource()
EB> methods need to be changed, only createViewResource().

FC> If we only want to do it for facelets, we would be done. But I
FC> thought this feature is about replacing any resource. If so we must
FC> also touch the other createResource* methods.

Yes, we do want to do it for all kinds of resource. Frank, can you
sketch out some text for the other createResource*() methods?

LU> Is it possible to use @ResourceDependency annotation to load a resource
LU> inside a resource library contract implementation? if the answer is yes, we need
LU> to do modifications in createResource() methods (META-INF/contracts is an
LU> alternate package type).

Yes, it is possible to do that.

[...]

EB> SECTION: changes to the ui: facelet tags

EB> <ui:composition> and <ui:decorate> will have an additional attribute,
EB> contract. If present, that name is taken to indicate that the named
EB> template must be used from the named resource library contract. If such
EB> a template is not found, it is an error, even if there is such a
EB> template available outside of contract.

FC> If the contract were just a prefix for the resources, we could
FC> simply reference the template absolutely (including the prefix).

LU> but if that so, there is no definition of the contract, which means
LU> the reusability will be limited. I'm not saying that we cannot do
LU> that, but in this case, I think it is clear this concept helps to
LU> keep things in order from start.

I understand the desire for that simplicity, but I'd rather formalize it
with an attribute. It's more toolable that way.

EB> ACTION: Will this assertion hold true if the contract itself has
EB> components that have @ResourceDependencies on resources inside and
EB> outside of the library? I think it will, but I need some oversight.

LU> I agree with you. The important part here is define the precedence (which one
LU> is scanned first, a library in META-INF/resources or a library in
LU> META-INF/contracts, but at the end, since there will not be a library with the
LU> same name in both folders, there is no need to worry about).

We can say that contracts is scanned first.

Ed

-- 
| edward.burns_at_oracle.com | office: +1 407 458 0017
| homepage:               | http://ridingthecrest.com/