Hi
LU>> in MyFaces the alias is prefixed according if is a facelet, view
LU>> metadata facelet or a composite component facelet. If I remember well,
LU>> the alias was used in the id generation, but I changed that part in
LU>> MyFaces with a better concept ( faceletId ). So, in MyFaces at the end
LU>> the "alias" is used only as debug information.
FC>> So it seems, that this is an implementation detail and not a spec problem.
Yes, it is an implementation detail.
LU>> Going back to the base example, if there is a file under
LU>> /templates/b.xhtml with a reference to:
LU>>
LU>> <ui:decorate template="dir2/mytemplate2.xhml">
LU>>
LU>> The resource should be located in:
LU>>
LU>> libraryName: N/A
LU>> resourceName: /templates/dir2/mytemplate2.xhtml
LU>>
LU>> Note if there is a resource in
LU>> META-INF/resources/templates/dir2/mytemplate2.xhtml, the resource
LU>> should not be taken into account (or maybe yes), because what we want
LU>> is resolve the resource in a relative way.
FC>> I think it should be taken into account. Since we are using the resource
FC>> handler to load facelets, they are resources.
Agreed, but we need to take a look carefully about when it is valid to take
them into account. For example consider this scenario:
webapp/
resources/
templates/
dir2/
mytemplate2.xhtml
templates/
dir2/
mytemplate2.xhtml
view1.xhtml
And inside templates/view1.xhtml
<ui:decorate template="dir2/mytemplate2.xhml">
The one that should be selected is /webapp/templates/dir2/mytemplate2.xhtml
and the one in resources should just be ignored, because in this case what's
inside resources is "out of scope".
In few words, the problem about allow to load files from "resources"
associate folders is that in that case there is the "library" concept, and
that one overlaps with a directory. For example for the resource:
resources/templates/dir2/mytemplate2.xhtml
It is possible to "call" it in these two ways:
- createResource("dir2/mytemplate2.xhtml", "templates")
- createResource("templates/dir2/mytemplate2.xhtml")
The problem about allow all resources to be loaded directly from facelets
engine, is that it makes possible to load resources that are supposed to
be open using libraryName/resourceName pair in the other way, and that's
not supposed to be like that.
But things are different when a composite component is considered. Since
a composite component can be located inside "resources" folder, relative
invocations of templates should be resolved under that context, but
absolute invocations do not.
LU>> The resolution process
LU>> inside a composite component is different than the resolution from a
LU>> template, but if the call is located inside a template called from a
LU>> composite component, it is relative to the composite component
LU>> library.
FC>> Should we enforce absolute references for that corner case?
Unfortunately, do that will break code that is running right now in JSF 2.0.
In my opinion, we should solve the problem right from the start, and "in
the way" we should define the rules over resource library contracts will
work. That will save us a lot of headaches later when people start do push
the concepts to its limits.
FC>> "... with your proposal it is no longer possible to have false
FC>> positives as discussed in ..."
If allow "false positives" or in other words, put resource library contracts
"on top" in the precendence order is useful, that's ok.
FC>> IMO, the only problem left is using ui:include from a composite
FC>> component. Shouldn't we simply specify that in that case we require
FC>> absolute references?
I think we should "just make things work". If the developer wants to use
template tags in composite components, that should work just fine. If the
develover creates a library that is not supposed to be found under the
webapp context, it should work just fine.
The big difference between a "resource library contract" and a "JSF
2.0 resource library" is that the "resource library contract" is supposed
to be attached to the webapp context or scope if and only if some
rules are complied.
Is allowed to define a composite component in a resource library contract?
In theory yes, and if a template is called in a relative way there,
createViewTemplateResource() should be called instead createResource().
If a composite component invokes a template in a absolute way, and that
template is defined under a resource library contract, that should work
too, but if the template is resolved in a relative way, I think the
template should be resolved under the context of where the composite
component was defined.
Maybe just mix resource library contracts with the current code in
createResource() is not a good idea after all, and we should make the
difference between resources created under a resource library contract
and other resources. Maybe we can fix that adding a method to
Resource class or some other methods to ResourceHandler. My intention is
just make light about the consequences and implications of the code as is
right now. It is up to you guys to define if it is worth to fix it and
if that so, how to do it.
regards,
Leonardo Uribe
2013/1/20 Frank Caputo <frank_at_frankcaputo.de>:
> Hi Leonardo,
>
> with your proposal it is no longer possible to have false positives as discussed in http://java.net/projects/javaserverfaces-spec-public/lists/users/archive/2012-11/message/89
>
> IMO, the only problem left is using ui:include from a composite component. Shouldn't we simply specify that in that case we require absolute references?
>
> Ciao Frank
>
> Am 17.01.2013 um 04:02 schrieb Leonardo Uribe <lu4242_at_gmail.com>:
>
>> Hi
>>
>> After thinking about the problem of ResourceHandler.createViewResource(),
>> I have an idea about how we can fix this part. Let's start for the
>> beginning (I'll do a small summary, fixing some parts to align the
>> concepts with the proposal, sorry if it becomes too repetitive):
>>
>> According to the new spec, we have some special places that store view related
>> resources:
>>
>> - META-INF/flows/<flow-name>/... : files there should be dealt as views.
>> - META-INF/contracts/<contract-name>/... : files there are not views but the
>> VDL should be able to load resources like templates that are used when a view
>> is processed. It also contains other resource files like .css, .png and so on
>> that the ResourceHandler should be able to locate and serve them. It also
>> contains composite component files.
>> - META_INF/resources/... : Contains resource files like .css, .png and so on
>> that the ResourceHandler should be able to locate and serve them. It also
>> contains composite component files.
>>
>> Since we have 3 different concepts here, it should be 3 different methods to
>> deal with this:
>>
>> - ResourceHandler.createResource(...) : (simplifying) resources loaded
>> using this method should scan these locations:
>>
>> * META-INF/contracts/<contract-name>/... in the classpath
>> * META_INF/resources/... in the classpath
>> * /resources/... in webapp folder
>>
>> - ResourceHandler.createViewTemplateResource(
>> FacesContext context, String resourceName) : load template files from
>> these locations:
>>
>> * /... in webapp folder
>> * META-INF/contracts/<contract-name>/...
>>
>> - ResourceHandler.createViewResource(
>> FacesContext context, String resourceName) : load files from these
>> locations:
>>
>> * /... in webapp folder
>> * META-INF/flows/<flow-name>/...
>>
>> Note it is necessary to define ordering of precedences here, but I'm
>> suggesting do it in this way.
>>
>> How a facelet resource should be loaded?
>>
>> - If the vdl is building a view by first time, call createViewResource(...).
>> - If a template is being loaded, call createViewTemplateResource(...).
>> - If a template is being loaded AND the call is relative,
>> call createViewTemplateResource(...).
>> - If a template is being loaded AND it is called from a composite
>> component or comes
>> from a composite component AND the call is absolute use
>> createViewTemplateResource(...).
>> - If a template is being loaded AND it is called from a composite
>> component or comes
>> from a composite component AND the call is relative, use createResource(...).
>> using the libraryName from the composite component (if any).
>> - If a composite component is being loaded, use createResource(...).
>>
>> To resolve a relative reference of a template, the suggested way is use the
>> "nearest parent" libraryName and the base "resourceName" or "path" of the
>> parent template.
>>
>> The proposal also suggest that Resource instances loaded from resource library
>> contract path has precedence over anything, which means if there are two
>> resources:
>>
>> META-INF/contracts/contractA/x.css
>>
>> and
>>
>> META-INF/resources/x.css
>>
>> In a call to createResource("x.css"), the instance returned will be the one
>> inside contracts. But the other side of the coin is that templates resolved
>> in a relative way can be overriden from a resource library contract, which
>> doesn't sound good, so maybe the precedence in createResource("...") should
>> be changed (it is up to you guys to decide which alternative is better).
>>
>> Note the solution proposed has effects like that in theory it is possible
>> to create a composite component inside a resource library contract.
>>
>> regards,
>>
>> Leonardo Uribe
>>
>> 2013/1/16 Leonardo Uribe <lu4242_at_gmail.com>:
>>> Hi Frank
>>>
>>> 2013/1/16 Frank Caputo <frank_at_frankcaputo.de>:
>>>> Hi Leonardo,
>>>>
>>>> Am 15.01.2013 um 20:37 schrieb Leonardo Uribe <lu4242_at_gmail.com>:
>>>>
>>>>> Thinking about this, I think a good idea could be add a method to
>>>>> Resource interface to get the last modified time.
>>>>>
>>>>> public Long getLastModified()
>>>>>
>>>>> return null if no lastModified time can be returned.
>>>>
>>>> This method would be really helpful, but I wouldn't allow null to be returned, so I'd use the primitive long as return value.
>>>>
>>>
>>> Ok. good to know that. The idea of the null is to know when there is
>>> no lastModified time, but maybe a -1 is better.
>>>
>>>> There will be an issue with decorating existing resources and overwriting only getLastModified. userAgentNeedsUpdate and getResponseHeaders won't call the decorated version of getLastModified. So on decorated resources all 3 methods must be implemented, which is not very comfortable.
>>>>
>>>
>>> The same hypotethical issue exists between userAgentNeedsUpdate and
>>> getResponseHeaders too, but the important consideration is how often
>>> is required to modify the last modified time? For "static" resources
>>> it will be always the same value, so the wrapper will not modify them.
>>> For resources that needs to be generated once (css + inner EL
>>> expressions), the same consideration applies (will not be modified).
>>> Resource instances like the one required by a captcha component (an
>>> image that is generated in a unique way per session), will have
>>> different implementations in those methods (usually getResponseHeaders
>>> return null userAgentNeedsUpdate return true and getLastModified
>>> return 0 or -1).
>>>
>>> In conclusion, in my opinion we shouldn't worry about that detail,
>>> because once these methods are defined, by the "nature" of the
>>> underlying Resource those implementations does not change.
>>>
>>>> Ciao Frank
>>>>
>>>>> 2013/1/15 Frank Caputo <frank_at_frankcaputo.de>:
>>>>>> Hi Leonardo,
>>>>>>
>>>>>> I recently provided a patch for Mojarra to solve this problem, which Manfred merged into the trunk ( http://java.net/projects/mojarra/sources/svn/diff/trunk/jsf-ri/src/main/java/com/sun/faces/facelets/impl/DefaultFacelet.java?rev1=11384&rev2=11385 ).
>>>>
>>>> Does this answer obsolete your older comments on resource library contracts?
>>>>
>>>
>>> No. I think use the alias for the calculation is not the right way to
>>> do it, because the alias has another different meaning. For example,
>>> in MyFaces the alias is prefixed according if is a facelet, view
>>> metadata facelet or a composite component facelet. If I remember well,
>>> the alias was used in the id generation, but I changed that part in
>>> MyFaces with a better concept ( faceletId ). So, in MyFaces at the end
>>> the "alias" is used only as debug information.
>>>
>>> In this case, DefaultFacelet must be modified to store the contextual
>>> library / resource and use that information to derive a relative
>>> resource. Suppose a composite component located in
>>> META-INF/resources/my.composite.component/simplecc.xhtml . It there is
>>> a reference to
>>>
>>> <ui:include src="dir1/resource.xhtml"/>
>>>
>>> The resource should be located in:
>>>
>>> libraryName: my.composite.component
>>> resourceName: dir1/resource.xhtml
>>>
>>> Going back to the base example, if there is a file under
>>> /templates/b.xhtml with a reference to:
>>>
>>> <ui:decorate template="dir2/mytemplate2.xhml">
>>>
>>> The resource should be located in:
>>>
>>> libraryName: N/A
>>> resourceName: /templates/dir2/mytemplate2.xhtml
>>>
>>> Note if there is a resource in
>>> META-INF/resources/templates/dir2/mytemplate2.xhtml, the resource
>>> should not be taken into account (or maybe yes), because what we want
>>> is resolve the resource in a relative way. The resolution process
>>> inside a composite component is different than the resolution from a
>>> template, but if the call is located inside a template called from a
>>> composite component, it is relative to the composite component
>>> library.
>>>
>>> Really this part is still open to interpretation, and it is clear we
>>> need to get to an agreement about how this should work.
>>>
>>> regards,
>>>
>>> Leonardo Uribe
>>>
>>>> Ciao Frank
>>>>
>>>>>>
>>>>>> I'll answer more detailed tomorrow.
>>>>>>
>>>>>> Ciao Frank
>>>>>>
>>>>>> Am 15.01.2013 um 00:32 schrieb Leonardo Uribe <lu4242_at_gmail.com>:
>>>>>>
>>>>>>> Right now, facelets derive the path using a call to:
>>>>>>>
>>>>>>> new URL(from, path)
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>
>
>