Hi Ok, I already send it. I hope it is clear the problem we are discussing about.
@Jakob: do you have any other issue related to the current implementation done in myfaces-commons-resourcehandler that we need to take a decision? regards, Leonardo Uribe 2011/6/30 Gerhard Petracek <[email protected]>: > ok - so please start a vote about it. > describe the topic and why you think something has to be changed > (compared to the original commit >in combination with< the addition > mentioned by martin). > please write it very concisely! we won't get a lot of votes, if the > description is too verbose. > > thx & regards, > gerhard > > 2011/6/30, Leonardo Uribe <[email protected]>: >> 2011/6/30 Gerhard Petracek <[email protected]>: >>> hi @ all, >>> >>> what jakob is talking about makes a lot of sense to me. >>> >>> @jakob: >>> please don't fork it. >>> >>> imo we should continue with the approach started by jakob + the >>> addition mentioned by martin. after finishing that we can think about >>> further improvements (if needed at all). >>> >>> @leo: >>> do you feel we need a vote about it? >>> >> >> Yes, it could be good. It is important to know the community opinion >> and follow that direction, no matter any personal opinion. After all, >> every development in myfaces are "community driven". Sometimes is >> difficult to ask the community, because you have to be very specific, >> but after the previous discussion we have a better idea about what to >> ask. >> >> regards, >> >> Leonardo Uribe >>> regards, >>> gerhard >>> >>> 2011/6/30, Jakob Korherr <[email protected]>: >>>> Hm, you're not getting it. This >>>> >>>>> To do it correctly we need to detect if this is a servlet 3.0 >>>>> container and do the necessary stuff, but we need to test what happen >>>>> if a 2.5 or 2.4 web.xml file is deployed on a 3.0 container. >>>>> Additionally, we need to take care about do not call 3.0 code in 2.5 >>>>> servlet container. This will not be an easy trick, I'm sure of it. >>>> >>>> was the idea at that point, but it wasn't done, b/c there was no time >>>> for it at that point. >>>> >>>> Unfortunately we two don't seem to get along here. Each one of us >>>> seems to have a very different idea of how this should be done and >>>> frankly I am tired of this discussion. Thus I created a fork of my >>>> initial resource-handler implementation (before you started >>>> committing) at a different code-hoster. This way everyone can >>>> implement what seems best for him/his users. >>>> >>>> Regards, >>>> Jakob >>>> >>>> 2011/6/30 Leonardo Uribe <[email protected]>: >>>>> 2011/6/30 Jakob Korherr <[email protected]>: >>>>>>> [...] 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.) >>>>> >>>>> It is new, because the idea is detect a valid prefix mapping when a >>>>> suffix mapping request is sent. The code inside >>>>> AdvancedResourceHandler didn't do that, it's more, assume something >>>>> about the environment it is not something good, its like do a bet. The >>>>> filter solution provide an algorithm to deal with all possible >>>>> configurations, and note the new strategy can be integrated with the >>>>> filter solution without any problem (i'm not thinking on the spec, >>>>> instead I'm thinking that the module is on myfaces commons and we can >>>>> do whatever we want). >>>>> >>>>> To do it correctly we need to detect if this is a servlet 3.0 >>>>> container and do the necessary stuff, but we need to test what happen >>>>> if a 2.5 or 2.4 web.xml file is deployed on a 3.0 container. >>>>> Additionally, we need to take care about do not call 3.0 code in 2.5 >>>>> servlet container. This will not be an easy trick, I'm sure of it. >>>>> >>>>> regards, >>>>> Leonardo >>>>> >>>>>> >>>>>> 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 >>>>>> >>>>> >>>> >>>> >>>> >>>> -- >>>> 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 >>> >> > > > -- > > http://www.irian.at > > Your JSF powerhouse - > JSF Consulting, Development and > Courses in English and German > > Professional Support for Apache MyFaces >
