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

[jsr372-experts] Re: [jsr372-experts mirror] Re: getResourcePaths like method for ResourceResolver

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Thu, 4 Aug 2016 00:18:35 -0500

Hi

I just wanted to mention that the algorithm in MyFaces does not have any
Faces Flow specific logic.

There is an algorithm that uses a set of "ResourceLoader" and
"ContractResourceLoader" instances, and there is a cache to reduce overhead.

But the chain used for createResource(...) and createViewResource(...) is
different, because the ordering is also different.

So, the proposal here has sense from spec perspective and looking MyFaces
code it is easy to walk through the different sets.

regards,

Leonardo Uribe

2016-07-28 12:09 GMT-05:00 arjan tijms <arjan.tijms_at_gmail.com>:

> Hi,
>
> I took a look at the current ResourceHandler implementation in Mojarra,
> and for view resources eventually what's being called for the #create()
> method is nothing more than:
>
> URL url = externalContext.getResource(path);
>
> Since this is by definition equal to ServletContext#getResource, it means
> that the default ResourceHandler can just call the
> ServletContext#getResourcePaths method.
>
> I do wonder a bit if complexity wise the ResourceHandler is not slightly
> sub-optimal, at least from an implementation perspective in Mojarra. While
> essentially only externalContext.getResource(path) is called, the following
> stack was necessary for that:
>
> Resource.getResourceUrl(FacesContext, String) line: 105
> FaceletWebappResourceHelper.findResource(LibraryInfo, String, String,
> boolean, FacesContext) line: 121
> ResourceManager.findResource(LibraryInfo, String, String, boolean,
> boolean, FacesContext) line: 539
> ResourceManager.getResourceInfo(String, String, String, String, boolean,
> boolean, FacesContext, LibraryInfo) line: 320
> ResourceManager.doLookup(String, String, String, boolean, boolean,
> List<String>, FacesContext) line: 285
> ResourceManager.findResource(String, String, String, boolean,
> FacesContext) line: 214
> ResourceHandlerImpl.createViewResource(FacesContext, String) line: 124
> ResourceHandlerImpl.createViewResource(FacesContext, String) line: 72
>
> Now a slightly deeper stack is not always a problem, but here all the
> classes involved are rather big and the methods have a very high cyclomatic
> complexity (number of paths through each method). Many methods take many
> parameters and then entire flows through the code each time do something
> based on whether say parameter one is not null and parameter 4 is false.
>
> Because of this it's not entirely trivial to see e.g. the "create view
> resource" flow in the above stack. Naming is a tad problematic too, e.g.
> what's the semantic difference between a "handler", "manager" and "helper"?
> And the helper is called FaceletWebappResourceHelper, but shouldn't this be
> something like ViewResourceHelper? (the call chain is supposed to be VDL
> neutral, isn't it?)
>
> There's also code there like shown below:
>
> boolean keepGoing = true;
> FacesContext context = FacesContext.getCurrentInstance();
> Application application = context.getApplication();
> FlowHandler fh = application.getFlowHandler();
> Flow currentFlow = fh.getCurrentFlow(context);
> do {
> if (null != currentFlow && 0 <
> currentFlow.getDefiningDocumentId().length()) {
> String definingDocumentId =
> currentFlow.getDefiningDocumentId();
> ExternalContext extContext =
> context.getExternalContext();
> ApplicationAssociate associate =
> ApplicationAssociate.getInstance(extContext);
> if
> (associate.urlIsRelatedToDefiningDocumentInJar(url, definingDocumentId)) {
> keepGoing = false;
> doNotCache = true;
> } else {
> if (matches.hasMoreElements()) {
> url = matches.nextElement();
> } else {
> keepGoing = false;
> }
> }
> } else {
> keepGoing = false;
> }
> } while (keepGoing);
>
> I'm not a big expert on flows, but shouldn't the ExternalContext and
> ApplicationAssociate be obtained once outside the loop, or can they change?
>
> Kind regards,
> Arjan Tijms
>
>
>
>
> On Wed, Jul 27, 2016 at 4:33 PM, arjan tijms <arjan.tijms_at_gmail.com>
> wrote:
>
>> Hi,
>>
>> On Wed, Jul 27, 2016 at 3:38 PM, Bauke Scholtz <balusc_at_gmail.com> wrote:
>>
>>> +1 only if it's visitable/filterable a la Files#walk
>>>
>>
>> Noted, thanks! Files#walk is indeed an important cornerstone.
>>
>> Kind regards,
>> Arjan Tijms
>>
>>
>>
>>>
>>> Cheers, B
>>>
>>> On Wed, Jul 27, 2016 at 3:27 PM, arjan tijms <arjan.tijms_at_gmail.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> On Wednesday, July 27, 2016, Leonardo Uribe <leonardo.uribe_at_irian.at>
>>>> wrote:
>>>>
>>>>> Just some small comments. There is a method called
>>>>> ResourceHandler.createViewResource(...) that returns a ViewResource
>>>>> instance, which is an interface with a method getURL(). This call
>>>>> ResourceResolver internally.
>>>>>
>>>>
>>>> Practically speaking indeed. I wrote about that here:
>>>> http://jdevelopment.nl/jsf-22/#809
>>>>
>>>> Theoretically speaking I think the spec doesn't require this, does it?
>>>>
>>>>
>>>>> There is nothing to scan for (possible) view resources or templates,
>>>>> but I suppose this feature should modify ResourceHandler instead
>>>>> ResourceResolver.
>>>>>
>>>>
>>>> For the best compatibility we may have to involve the ResourceResolver.
>>>> The primary change would be adding the method to ResourceHandler though.
>>>>
>>>> Kind regards,
>>>> Arjan Tijms
>>>>
>>>>
>>>>
>>>>> regards,
>>>>>
>>>>> Leonardo Uribe
>>>>>
>>>>> 2016-07-26 17:38 GMT-05:00 arjan tijms <arjan.tijms_at_gmail.com>:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> The ServletContext has a method to acquire all paths to resources
>>>>>> within a web application; getResourcePaths().
>>>>>>
>>>>>> In JSF resources are handled by the ResourceResolver. This has a
>>>>>> method createViewResource that takes a path and effectively returns a URL,
>>>>>> just like ServletContext has a getResource method taking a path and
>>>>>> returning a URL.
>>>>>>
>>>>>> In both cases, the usage is to abstract the actual location of
>>>>>> resources, which could therefor transparently be on a local or remote
>>>>>> filesystem, in a database, custom jar location, or whatever.
>>>>>>
>>>>>> The JSF specific ResourceResolver however does not have a
>>>>>> getResourcePaths() equivalent. I'd like to propose to rectify this by
>>>>>> introducing such method for JSF view resources.
>>>>>>
>>>>>> Since we're targeting JDK 8 such method could take inspiration from
>>>>>> Files#walk (
>>>>>> https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#walk-java.nio.file.Path-java.nio.file.FileVisitOption...-
>>>>>> )
>>>>>>
>>>>>> At least one use case would be for something like the FaceViews
>>>>>> feature in OmniFaces, but I'd like to design this feature not just for
>>>>>> that, of course. Another use case for instance would be for help in
>>>>>> debugging (providing a list of all resources handled by the system could be
>>>>>> handy to check for omissions or unexpected entries)
>>>>>>
>>>>>> Thoughts?
>>>>>>
>>>>>> Kind regards,
>>>>>> Arjan Tijms
>>>>>>
>>>>>
>>>>>
>>>
>>
>