> [...] The new alternative proposed is similar. This alternative is not "new"! My first version of the AdvancedResourceHandler (before you started committing) already did exactly this! (However, assuming /faces/* as mapping if the page was accessed via suffix mapping, but making it configurable would have done the job too.)
Regards, Jakbo 2011/6/30 Leonardo Uribe <[email protected]>: > Hi Jakob > > 2011/6/30 Jakob Korherr <[email protected]>: >> Hi Martin, >> >> Thank you so much for your mail! >> >> This is exactly my point of view about the ResourceHandler. However, >> Leonardo in I kinda got into a "fight" about it and unfortunately, I >> do not have time for that right now! > > For me this is just a work that we need to do. Don't get me wrong. My > intention is build this stuff correctly, and if I see a problem, I'll > discuss it and fix it. In fact, I'm taking concrete actions to add the > features I proposed into the module, and change some other things that > just needs more work. > >> >> Leonardo, please reconsider my reasoning from the previous mails of >> this discussion. >> > > Now we have found an alternative to get rid the filter stuff and use > only FacesServlet. > >>>the resource url should then always be generated with the prefix >>>mapping - how can this lead to inconsistencies? >> >> I also don't think there could be inconsistencies. However, Leonardo >> thinks so, but unfortunately he could not give an example. >> > > I gave you the use case. Look this fragment on a previous mail: > > "... If a page is rendered using suffix mapping, resource paths will > use that and not prefix mapping, because faces mapping is derived from > the request path ..." > > The filter did solve the problem, because it provided a way to detect > itself and generate a valid prefixed url. The new alternative proposed > is similar. > > regards, > > Leonardo Uribe > >> Regards, >> Jakob >> >> 2011/6/30 Martin Marinschek <[email protected]>: >>> Hi guys, >>> >>> let me weigh in on the filter question: please, no filter! >>> >>> @prefix suffix mappings: you can get the registered mappings >>> >>> in previous servlet versions: parsing the web.xml >>> in servlet 3.0: via the API >>> http://download.oracle.com/javaee/6/api/javax/servlet/ServletRegistration.html >>> >>> the resource url should then always be generated with the prefix >>> mapping - how can this lead to inconsistencies? >>> >>> best regards, >>> >>> Martin >>> >>> On Thu, Jun 23, 2011 at 11:54 PM, Leonardo Uribe <[email protected]> wrote: >>>> Hi >>>> >>>> In the last days this enhancements were commited: >>>> >>>> ------------------------------------------------------------------------------ >>>> >>>> Added GZIP compression to ExtendedResourceHandler and these params: >>>> >>>> /** >>>> * Enable or disable gzip compressions for resources served by >>>> this extended resource handler. By default is disabled (false). >>>> */ >>>> @JSFWebConfigParam(defaultValue="false") >>>> public static final String INIT_PARAM_GZIP_RESOURCES_ENABLED = >>>> "org.apache.myfaces.commons.GZIP_RESOURCES_ENABLED"; >>>> >>>> /** >>>> * Indicate the suffix used to recognize resources that should be >>>> compressed. By default is ".css .js". >>>> */ >>>> @JSFWebConfigParam(defaultValue=".css, .js") >>>> public static final String INIT_PARAM_GZIP_RESOURCES_SUFFIX = >>>> "org.apache.myfaces.commons.GZIP_RESOURCES_SUFFIX"; >>>> public static final String >>>> INIT_PARAM_GZIP_RESOURCES_EXTENSIONS_DEFAULT = ".css .js"; >>>> >>>> /** >>>> * Indicate if gzipped files are stored on a temporal directory to >>>> serve them later. By default is true. If this is >>>> * disable, the files are compressed when they are served. >>>> */ >>>> @JSFWebConfigParam(defaultValue="true") >>>> public static final String INIT_PARAM_CACHE_DISK_GZIP_RESOURCES = >>>> "org.apache.myfaces.commons.CACHE_DISK_GZIP_RESOURCES"; >>>> >>>> by default compression is set to false. It could be good to enable >>>> compression only on files bigger than some specified lenght, to allow >>>> finer tuning. >>>> >>>> ------------------------------------------------------------------------------ >>>> >>>> >>>> and these enhancements: >>>> >>>> >>>> ------------------------------------------------------------------------------ >>>> >>>> Added new scanning and parsing of myfaces-resources-config.xml files. >>>> It was added this param: >>>> >>>> /** >>>> * This param allow to override the default strategy to locate >>>> myfaces-resources-config.xml files, that will be parsed later. In this >>>> way >>>> * it is possible to include new source locations or handle cases >>>> like OSGi specific setup. >>>> */ >>>> @JSFWebConfigParam >>>> public static final String >>>> INIT_PARAM_EXTENDED_RESOURCE_HANDLER_CONFIG_URL_PROVIDER = >>>> "org.apache.myfaces.commons.EXTENDED_RESOURCE_HANDLER_CONFIG_URL_PROVIDER"; >>>> >>>> I think just a param that instantiate a class implementing >>>> MyFacesResourceHandlerUrlProvider is enough. The default algorithm >>>> loook on classpath for META-INF/myfaces-resources-config.xml and on >>>> servlet context for WEB-INF/myfaces-resources-config.xml files. >>>> >>>> myfaces-resources-config.xml files can be used with these options: >>>> >>>> <?xml version="1.0" encoding="UTF-8"?> >>>> <myfaces-resources-config> >>>> <!-- Mark this library to be handled by Extended Resource Handler --> >>>> <library> >>>> <library-name>libraryA</library-name> >>>> </library> >>>> >>>> <!-- Indicate this library has another name, so if libraryC is used, >>>> resources should be redirected to libraryC1 --> >>>> <library> >>>> <library-name>libraryC</library-name> >>>> <redirect-name>libraryC1</redirect-name> >>>> </library> >>>> >>>> <!-- Allow to customize the request path generated, to do things like >>>> take library resources from a Content Delivery Network (CDN) or just >>>> take it directly from an specified location. Note it is responsibility >>>> of the developer to configure it properly, and the resources should >>>> exists locally under the library name selected. --> >>>> <library> >>>> <library-name>libraryB</library-name> >>>> >>>> <request-path>http://someaddress.com/alternatePath/#{resourceName}</request-path> >>>> <!-- This example shows the variables that can be called >>>> inside the expression to construct the request map >>>> <request-path>#{extensionMapping ? '' : >>>> mapping}/javax.faces.resource/$/#{localePrefix}/#{libraryName}/#{resourceName}#{extensionMapping >>>> ? mapping : ''}</request-path> >>>> --> >>>> </library> >>>> >>>> </myfaces-resources-config> >>>> >>>> All libraries referenced here will be handled by the extended >>>> ResourceHandler. Additionally, there is an option to redirect a >>>> library name into another, to deal with possible conflicts between >>>> resources loaded, specially javascript libraries. And finally there is >>>> an option to override the request-path with an EL expression, so if >>>> you have a library with some static resources it is easy to construct >>>> an url to load them from a Content Delivery Network (CDN) or just from >>>> some specified path. The only thing you should note is the library >>>> should exists locally under the library name, to detect when a >>>> resource can be resolved or not. >>>> >>>> ------------------------------------------------------------------------------ >>>> >>>> I have not tested it fully, but in my opinion it looks good. I has the >>>> best of the previous AdvancedResourceHandler with some new valuable >>>> features proposed. >>>> >>>> If no objections I'll remove the previous code, since it was >>>> integrated on the alternate solution. >>>> >>>> Suggestions and tomatoes are welcome >>>> >>>> Leonardo Uribe >>>> >>>> 2011/6/14 Leonardo Uribe <[email protected]>: >>>>> Hi Jakob >>>>> >>>>> 2011/6/14 Jakob Korherr <[email protected]>: >>>>>> Hi Leonardo, >>>>>> >>>>>>>Because set prefix and suffix mapping for the same webapp could lead >>>>>>>to inconsistencies. >>>>>> >>>>>> Which inconsistencies exactly? Please give an example, I can't really >>>>>> think of any! >>>>>> >>>>> >>>>> Let's take a look to AdvanceResource.getRequestPath: >>>>> >>>>> public String getRequestPath() >>>>> { >>>>> FacesContext facesContext = FacesContext.getCurrentInstance(); >>>>> StringBuilder path = new StringBuilder(); >>>>> path.append(ResourceUtils.getFacesServletPrefix(facesContext)); >>>>> ..... >>>>> >>>>> Now look on getFacesServletPrefix: >>>>> >>>>> public static String getFacesServletPrefix(FacesContext facesContext) >>>>> { >>>>> ExternalContext externalContext = >>>>> facesContext.getExternalContext(); >>>>> Map<String, Object> applicationMap = >>>>> externalContext.getApplicationMap(); >>>>> >>>>> // check if already cached >>>>> String prefix = (String) >>>>> applicationMap.get(FACES_SERVLET_PREFIX_KEY); >>>>> if (prefix == null) >>>>> { >>>>> // try to extract it from current request >>>>> prefix = getFacesServletPrefixMapping(facesContext); >>>>> .... >>>>> >>>>> public static String getFacesServletPrefixMapping(FacesContext >>>>> facesContext) >>>>> { >>>>> ExternalContext externalContext = >>>>> facesContext.getExternalContext(); >>>>> >>>>> String pathInfo = externalContext.getRequestPathInfo(); >>>>> String servletPath = externalContext.getRequestServletPath(); >>>>> >>>>> if (pathInfo != null) >>>>> { >>>>> return servletPath; >>>>> } >>>>> else >>>>> { >>>>> // In the case of extension mapping, no "extra path" is >>>>> available. >>>>> // Still it's possible that prefix-based mapping has been used. >>>>> // Actually, if there was an exact match no "extra path" >>>>> // is available (e.g. if the url-pattern is "/faces/*" >>>>> // and the request-uri is "/context/faces"). >>>>> int slashPos = servletPath.lastIndexOf('/'); >>>>> int extensionPos = servletPath.lastIndexOf('.'); >>>>> if (extensionPos > -1 && extensionPos > slashPos) >>>>> { >>>>> // we are only interested in the prefix mapping >>>>> return null; >>>>> } >>>>> else >>>>> { >>>>> // There is no extension in the given servletPath and >>>>> therefore >>>>> // we assume that it's an exact match using >>>>> prefix-based mapping. >>>>> return servletPath; >>>>> } >>>>> } >>>>> } >>>>> >>>>> The code takes pathInfo/servletPath information and prepend it to the >>>>> beggining. The first bug is the code prepend the extension when suffix >>>>> mapping is used!. But look the mapping is saved on the application >>>>> map. So on further request, the mapping is retrieved from application >>>>> map, so if the first request is suffix mapping, all later resource >>>>> request paths will be generated wrong, even if prefix mapping is used. >>>>> >>>>> The problem is to know if prefix mapping is used you should parse >>>>> web.xml file, but that's wrong, because in servlet 3.0 spec you don't >>>>> necessary have that file (web fragment?). In conclusion there is no >>>>> way to "detect" and generate the mapping correctly. >>>>> >>>>> The nice part about the filter is you can put some code to detect >>>>> automatically if the filter is registered or not and act according. >>>>> This is the param: >>>>> >>>>> /** >>>>> * Indicate if this filter is being used to process request. It >>>>> works in three modes: >>>>> * >>>>> * <ul> >>>>> * <li>true: assume the filter is correctly setup.</li> >>>>> * <li>check: check if the filter has been setup and if that so, >>>>> use it. Otherwise, it uses FacesServlet (use prefix mapping to make >>>>> all features work).</li> >>>>> * <li>false: filter is not used at all.</li> >>>>> * </ul> >>>>> */ >>>>> @JSFWebConfigParam(defaultValue="check", expectedValues="true, >>>>> false, check") >>>>> public static final String INIT_PARAM_USE_EXTENDED_RESOURCE_FILTER >>>>> = "org.apache.myfaces.commons.USE_EXTENDED_RESOURCE_FILTER"; >>>>> public static final String >>>>> INIT_PARAM_USE_EXTENDED_RESOURCE_FILTER_DEFAULT = "check"; >>>>> >>>>> In this way, there will not be inconsistencies, because we have the >>>>> three options: >>>>> >>>>> - If prefix mapping is used -> prepend the prefix >>>>> - If suffix mapping is used and no filter setup -> use suffix mapping >>>>> like always >>>>> - If suffix mapping is used and filter setup -> use filter prefix mapping >>>>> >>>>>>>[...] If a page is rendered using suffix mapping, >>>>>>>resource paths will use that and not prefix mapping, because faces >>>>>>>mapping is derived from the request path. >>>>>> >>>>>> Nope. That's the whole point of the AdvancedResourceHandler. It always >>>>>> uses prefix mapping, regardless of what the current page is using!! >>>>>> Just check the code (before your commit) ;) >>>>>> >>>>> >>>>> As you can see, I have found many bugs in the previous code. I usually >>>>> take my time to check this stuff. In fact, I implemented all >>>>> ResourceHandler implementation in MyFaces, and other alternate >>>>> implementations on tomahawk and sandbox for different use cases, so I >>>>> know step by step what says the spec and how the code works. >>>>> >>>>>> I have to say I am not a real fan of this filter. It's like in the old >>>>>> days.. with tomahawk... >>>>>> >>>>> >>>>> Note every JSF library uses a filter! Trinidad, RichFaces, PrimeFaces, >>>>> IceFaces. It could be good to find a solution without use a filter but >>>>> based on the previous discussion I don't see any. I don't get the >>>>> point. If you have a better idea please send your comments. >>>>> >>>>> I think the strategy proposed is an advance, because you only use it >>>>> when it is necessary. The other alternative is tell users don't use >>>>> suffix mapping. >>>>> >>>>>>> I think the opposite in this case, because the previous syntax is >>>>>>> ambiguous, so you can't decide how to get the libraryName and >>>>>>> resourceName from the resourceBasePath, and the spec requires describe >>>>>>> that in a explicit way. Think about a resource on: >>>>>>> >>>>>>> /de/mydir/myresource.js (resourceName="de/mydir/myresource.js") >>>>>>> >>>>>>> will produce this request path: >>>>>>> >>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/de_AT/mydir/myresource.js >>>>>>> >>>>>>> The algorithm will detect de as a locale prefix, mydir as a library >>>>>>> and myresource.js as a resource name, but that's wrong because the >>>>>>> resource name is de/mydir/myresource.js. >>>>>> >>>>>> I am sorry, but this is wrong, Leo. >>>>>> >>>>>> At first a resourceName of "de/mydir/myresource.js" should not be >>>>>> used. It should rather be resourceName="myresource.js" and >>>>>> libraryName="de/mydir". I know the spec does not explicitly tell us >>>>>> that the resourceName must not be a path, but it is the only way it >>>>>> really makes sence, if you think about it. Otherwise separation of >>>>>> libraryName and resourceName would not be necessary! >>>>>> >>>>> >>>>> The problem is "should not be used" is not an option. I'm saying here >>>>> that the same url could be handled by both the default and the >>>>> proposed method. Assume that a developer will do everything you >>>>> imagine is not very realistic. >>>>> >>>>>> Furthermore, a resourceName of "de/mydir/myresource.js" would produce >>>>>> the following path (you did skip "de" and "faces"): >>>>>> >>>>>> http://{server}[:port]/{appPath}/faces/javax.faces.resource/de_AT/de/mydir/myresource.js >>>>>> >>>>>> ..thus producing a resource with libraryName="de/mydir" and >>>>>> resourceName="myresource.js". And this is exactly what is expected of >>>>>> it!! >>>>> >>>>> No, because "de" is a valid locale!. >>>>> >>>>> I think that the relationship between Resource instances and request >>>>> paths generated should be 1:1 and should be symmetric. That means, if >>>>> I call this code from a renderer: >>>>> >>>>> ResourceHandler.createResource("","","de/mydir/myresource.js"); >>>>> >>>>> Later the ResourceHandler implementation, when >>>>> handleResourceRequest(FacesContext) is called should call the same >>>>> method, but instead it will call: >>>>> >>>>> ResourceHandler.createResource("de","mydir","myresource.js"); >>>>> >>>>> Who should attend the request? the extended resource handler or the >>>>> default one. The first call expect the default one, but the second?. >>>>> >>>>> In conclusion, if the example does not fulfit the two conditions (be >>>>> 1:1 and symmetric), for any imaginable Resource instance, it will not >>>>> be correctly specified. >>>>> >>>>>> >>>>>>> Anyway we need something to "diferentiate" between the old and the >>>>>>> alternate syntax, so use '$/' is as good as any other we can imagine. >>>>>> >>>>>> I don't think we need to do this differentiation in the first place. I >>>>>> see no reason for it. My code in MyFaces commons (before you committed >>>>>> your stuff) did not use it either and it worked well! Of course, I did >>>>>> not have this filter, but I don't like that anyway (see above). >>>>>> >>>>> >>>>> Why don't you like it? do you have something better in mind?. If you >>>>> want I change of opinion, please provide me with arguments to think >>>>> the opposite. I'm always open to any suggestions or critics. >>>>> >>>>>>> My interest is put this as a module for JSF 2.0, because there is >>>>>>> nothing that prevent us doing it, and this is the "base stone" to make >>>>>>> components with libraries like dojo, that requires load modules from >>>>>>> derived base paths. After that, we can push this on the spec for JSF >>>>>>> 2.2 and the EG will decide. >>>>>> >>>>>> That's the general idea. And note that I am the guy working on the >>>>>> resource handler stuff in the JSF 2.2 EG ;) >>>>>> >>>>>> >>>>>> One more note at the end: actually I am not very happy that you >>>>>> committed your code directly into the svn without providing it as >>>>>> patch before. You did not do any work on the AdvancedResourceHandler >>>>>> before (it was all my code) and it was a pretty big commit (even took >>>>>> 2 commit-mails). Thus you gave me no choice to take a look at it and >>>>>> discuss the changes with you. If I did something like this, the first >>>>>> thing you would do is reverting my commit and providing it as patch so >>>>>> that we can discuss it. I won't do that, but actually it's kinda >>>>>> annoying... >>>>>> >>>>> >>>>> I commited the code instead create a patch, because the code commited >>>>> does not override the previous code. So you can put the two solutions >>>>> side by side and compare them in a easier way. If something doesn't >>>>> like us, we can remove the added files and that's it, there is no harm >>>>> or you don't have to do something difficult to revert the code, >>>>> right?. Note the code has not released yet, so we don't have to >>>>> preserve the package or the class name or any structure. >>>>> >>>>> Things are different when you have already code and you need to >>>>> "override" something, to include something new. A patch is better in >>>>> that case. But in this case, I'm working on a completely different >>>>> solution from scratch. >>>>> >>>>> regards, >>>>> >>>>> Leonardo Uribe >>>>> >>>>>> Regards, >>>>>> Jakob >>>>>> >>>>>> 2011/6/14 Leonardo Uribe <[email protected]>: >>>>>>> Hi Jakob >>>>>>> >>>>>>> 2011/6/13 Jakob Korherr <[email protected]>: >>>>>>>> Hi Leo, >>>>>>>> >>>>>>>> Overall this seems nice, thanks! >>>>>>>> >>>>>>>> However, I have some comments on your solution: >>>>>>>> >>>>>>>> 1) If I have to configure a Filter in web.xml I can just as good >>>>>>>> define a prefix mapping for the FacesServlet. I don't see why an >>>>>>>> additional Filter is better than an additional servlet-mapping. So why >>>>>>>> exactly? >>>>>>>> >>>>>>> >>>>>>> Because set prefix and suffix mapping for the same webapp could lead >>>>>>> to inconsistencies. If a page is rendered using suffix mapping, >>>>>>> resource paths will use that and not prefix mapping, because faces >>>>>>> mapping is derived from the request path. >>>>>>> >>>>>>> We can't change FacesServlet to only handle resource request for a >>>>>>> specific mapping, but with the filter this is done by default. Note >>>>>>> the filter will be used only when suffix mapping is used. I tried it >>>>>>> using FacesServlet but it is useless, because you should do changes on >>>>>>> jsf impl, so at the end it will only work on myfaces, and the >>>>>>> intention is provide it as a module for any jsf implementation. >>>>>>> >>>>>>>> 2) The locale in the resource path really is essential, please do NOT >>>>>>>> remove it. I did a lot of tests with different browsers about this and >>>>>>>> you just cannot verify that every user will get the right (localized) >>>>>>>> resource, if the user's locale is not on the request path. The two >>>>>>>> main problems here are: a) the user changes the locale, but the >>>>>>>> browser uses the cached resource (with the old locale), because it >>>>>>>> cannot know that it has changed (some browsers will not even start a >>>>>>>> request for it) - however, if the locale is in the path, it will >>>>>>>> change and thus the browser will trigger a new request for the >>>>>>>> resource. b) you cannot really know if there are multiple versions of >>>>>>>> a resource for different locales, because you should not scan all jar >>>>>>>> files for them (--> remember the performance-issue we had with this >>>>>>>> stuff) and furthermore the classpath might change! >>>>>>>> >>>>>>> >>>>>>> Ok, good to know that. The current code works "forcing" output the >>>>>>> locale, so we can just let things as is. >>>>>>> >>>>>>>> 3) >>>>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/{locale}/{libraryName}/[resourceName] >>>>>>>>> >>>>>>>>> Unfortunately, this syntax is ambiguous, because it is not possible to >>>>>>>>> identify if the request should be handled by the default algorithm or >>>>>>>>> by the "extended" ResourceHandler. So I tried this one on >>>>>>>>> ExtendedResourceHandler: >>>>>>>>> >>>>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/$/{locale}/{libraryName}/[resourceName] >>>>>>>> >>>>>>>> This is a nice idea, but I guess this will not be an option for the >>>>>>>> JSF 2.2 resource handler (which will most likely be a modified version >>>>>>>> of the AdvancedResourceHandler). >>>>>>>> >>>>>>> >>>>>>> I think the opposite in this case, because the previous syntax is >>>>>>> ambiguous, so you can't decide how to get the libraryName and >>>>>>> resourceName from the resourceBasePath, and the spec requires describe >>>>>>> that in a explicit way. Think about a resource on: >>>>>>> >>>>>>> /de/mydir/myresource.js (resourceName="de/mydir/myresource.js") >>>>>>> >>>>>>> will produce this request path: >>>>>>> >>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/de_AT/mydir/myresource.js >>>>>>> >>>>>>> The algorithm will detect de as a locale prefix, mydir as a library >>>>>>> and myresource.js as a resource name, but that's wrong because the >>>>>>> resource name is de/mydir/myresource.js. >>>>>>> >>>>>>> Anyway we need something to "diferentiate" between the old and the >>>>>>> alternate syntax, so use '$/' is as good as any other we can imagine. >>>>>>> My interest is put this as a module for JSF 2.0, because there is >>>>>>> nothing that prevent us doing it, and this is the "base stone" to make >>>>>>> components with libraries like dojo, that requires load modules from >>>>>>> derived base paths. After that, we can push this on the spec for JSF >>>>>>> 2.2 and the EG will decide. >>>>>>> >>>>>>> regards, >>>>>>> >>>>>>> Leonardo Uribe >>>>>>> >>>>>>>> >>>>>>>> Please take this stuff into account - thanks! >>>>>>>> >>>>>>>> Regards, >>>>>>>> Jakob >>>>>>>> >>>>>>>> 2011/6/14 Leonardo Uribe <[email protected]>: >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> I committed on myfaces-commons-resourcehandler module on trunk an >>>>>>>>> alternative solution for this issue. It is still not complete, so the >>>>>>>>> idea is discuss it. See: >>>>>>>>> >>>>>>>>> https://issues.apache.org/jira/browse/MFCOMMONS-33 >>>>>>>>> >>>>>>>>> From previous discussion, on AdvancedResource handler we have: >>>>>>>>> >>>>>>>>> a. relative paths between resources (css files referencing images >>>>>>>>> without using #resource['..']) >>>>>>>>> b. caching resources in the client (disabled if ProjectStage == >>>>>>>>> Development) >>>>>>>>> c. GZIP compression and local cache in tmp dir (disabled if >>>>>>>>> ProjectStage == Development) >>>>>>>>> d. i18n (supporting country code and language). >>>>>>>>> >>>>>>>>> We had the following proposals: >>>>>>>>> >>>>>>>>> 1. reutilize resource information to prevent unnecessary calls to >>>>>>>>> getResource() (shared ResourceCache). >>>>>>>>> 2. Alternate xml file >>>>>>>>> 3. Make it work with suffix mapping. >>>>>>>>> 4. Add a SPI interface to delegate .xml resource scanning. >>>>>>>>> 5. Use content delivery network (CDN) to load known javascript or >>>>>>>>> other >>>>>>>>> resource files like jQuery or prototype. >>>>>>>>> >>>>>>>>> The objective is provide a solution for all those wanted features. >>>>>>>>> >>>>>>>>> The most important one is number 3. (make it work with suffix >>>>>>>>> mapping), because it limits the scope where a. (relative paths between >>>>>>>>> resources) could be applied. Use a parse on some files it is not a >>>>>>>>> very good solution, so I tried to found an alternative. The most >>>>>>>>> simple one is use a filter that just do the "resource handling" part, >>>>>>>>> just like FacesServlet does. So with suffix mapping you only need to >>>>>>>>> add this on web.xml file: >>>>>>>>> >>>>>>>>> <filter> >>>>>>>>> <filter-name>Faces Filter</filter-name> >>>>>>>>> >>>>>>>>> <filter-class>org.apache.myfaces.commons.resourcehandler.filter.ResourceHandlerFilter</filter-class> >>>>>>>>> </filter> >>>>>>>>> >>>>>>>>> <filter-mapping> >>>>>>>>> <filter-name>Faces Filter</filter-name> >>>>>>>>> <url-pattern>/javax.faces.resource/*</url-pattern> >>>>>>>>> </filter-mapping> >>>>>>>>> >>>>>>>>> and that's it. In this way, there is no need to any parser, just put >>>>>>>>> the files on a library, register it on the xml file. If you are using >>>>>>>>> prefix mapping for Faces Servlet, you will not need that entry, >>>>>>>>> because everything will be handled from Faces Servlet. >>>>>>>>> >>>>>>>>> With this solution, javascript libraries like dojo that loads files or >>>>>>>>> have css resources with url(...) entries will work without any >>>>>>>>> changes. >>>>>>>>> >>>>>>>>> I have seen this issue: >>>>>>>>> >>>>>>>>> https://issues.apache.org/jira/browse/MFCOMMONS-30 >>>>>>>>> Change URL management of Advanced JSF 2 ResourceHandler >>>>>>>>> >>>>>>>>> The idea was use this >>>>>>>>> >>>>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/{locale}/{libraryName}/[resourceName] >>>>>>>>> >>>>>>>>> Unfortunately, this syntax is ambiguous, because it is not possible to >>>>>>>>> identify if the request should be handled by the default algorithm or >>>>>>>>> by the "extended" ResourceHandler. So I tried this one on >>>>>>>>> ExtendedResourceHandler: >>>>>>>>> >>>>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/$/{locale}/{libraryName}/[resourceName] >>>>>>>>> >>>>>>>>> The first $ caracter says this extension should be handled by the >>>>>>>>> ExtendedResourceHandler. We can go further and allow this notation: >>>>>>>>> >>>>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/$$/{libraryName}/[resourceName] >>>>>>>>> >>>>>>>>> In this way there is no ambiguity, and we don't need to force locale >>>>>>>>> to be output. This could be possible too: >>>>>>>>> >>>>>>>>> http://{server}[:port]/{appPath}/javax.faces.resource/$$$/[resourceName] >>>>>>>>> >>>>>>>>> But that it is not really necessary at all. >>>>>>>>> >>>>>>>>> The proposed code still does not contains the options for GZIP >>>>>>>>> compression, because the previous algorithm does not take into account >>>>>>>>> what happen on concurrent requests (two threads modifying the same >>>>>>>>> file at the same time). I did an algorithm for sandbox for JSF 2.0 >>>>>>>>> s:roundedPanel. It uses an application scope map and some synchronized >>>>>>>>> blocks to ensure only one thread writes the file. Exactly the same >>>>>>>>> pattern works in this case, so the only thing we need to do is >>>>>>>>> refactor that code and put it here. >>>>>>>>> >>>>>>>>> Does that sounds good? if no objections commit the proposals here >>>>>>>>> soon. >>>>>>>>> >>>>>>>>> regards, >>>>>>>>> >>>>>>>>> Leonardo Uribe >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Jakob Korherr >>>>>>>> >>>>>>>> blog: http://www.jakobk.com >>>>>>>> twitter: http://twitter.com/jakobkorherr >>>>>>>> work: http://www.irian.at >>>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Jakob Korherr >>>>>> >>>>>> blog: http://www.jakobk.com >>>>>> twitter: http://twitter.com/jakobkorherr >>>>>> work: http://www.irian.at >>>>>> >>>>> >>>> >>> >>> >>> >>> -- >>> >>> http://www.irian.at >>> >>> Your JSF powerhouse - >>> JSF Consulting, Development and >>> Courses in English and German >>> >>> Professional Support for Apache MyFaces >>> >> >> >> >> -- >> Jakob Korherr >> >> blog: http://www.jakobk.com >> twitter: http://twitter.com/jakobkorherr >> work: http://www.irian.at >> > -- Jakob Korherr blog: http://www.jakobk.com twitter: http://twitter.com/jakobkorherr work: http://www.irian.at
