jsr344-experts@javaserverfaces-spec-public.java.net

[jsr344-experts] Re: PRD Review and pending issues

From: Leonardo Uribe <lu4242_at_gmail.com>
Date: Wed, 23 Jan 2013 21:09:16 -0500

Hi

2013/1/23 Frank Caputo <frank_at_frankcaputo.de>:
> Hi Leonardo,
>
> Am 21.01.2013 um 00:43 schrieb Leonardo Uribe <lu4242_at_gmail.com>:
>
>> 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.
>
> If we enforce absolute references in that corner case together with contracts, we won't break existing code, because contracts are new. So we could simply fall back to new URL(from, path) for that case.

Maybe we have a misunderstanding here. Consider this case:

META-INF/resource/my.custom.cclib/testComp.xhtml
META-INF/resource/my.custom.cclib/mytemplate.xhtml

testComp is a composite component, but mytemplate is not.

Inside the composite component you have something like this:

<ui:decorate template="mytemplate.xhtml"/>

That works right now in jsf 2.0. If by some reason a contract has that
name as a template, it will conflict with the composite component.

In few words what I want is keep this use case working.

If a composite component uses a template that is supposed to be
defined in a resource library contract, we can enforce that the
composite component needs to load the template in a absolute
way:

<ui:decorate template="/mytemplate.xhtml"/>

That's ok.

Note I really want to get rid of new URL(from, path), because that's not
the right way to deal with this, and that causes a lot of trouble. I think with
this proposal we are very close to get it done. The only thing left is work
a little bit more on the details.

>
>> 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?
>
> IMO, it should (I've seen it working in customer's project and it's really useful).
>
>> 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,
>
> I think, this should work currently.
>
>> 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.
>
> If you are using contracts, you would expect them to work also in this case. So we should be able to compute some kind of absolute path.
>

That's the idea. Find an algorithm that according to the context and the
relative path, it can derive an standard way to get the resource in a
absolute way. If a composite component is in a resource library, the
libraryName should be used to resolve templates in a relative way,
and so on.

>> 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.
>
> I would be happy with a method String getContract() in Resource. I think this would help solving this problem.
>

That would help to define the "context".

>> 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.
>
> Any ideas from any other volunteers?
>
> Ciao Frank
>

regards

Leonardo Uribe
>>
>> 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)
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>
>>>
>>>
>>
>
>