Details

      Description

      myfaces-commons-resourcehandler module includes an "AdvancedResourceHandler" with these objectives:

      • relative paths between resources (css files referencing images without using #resource['..'])
      • caching resources in the client (disabled if ProjectStage == Development)
      • GZIP compression and local cache in tmp dir (disabled if ProjectStage == Development)
      • i18n (supporting country code and language).

      This requires more discussion and work to create a full solution. In order to create a enhanced implementation, I have a proposal on this issue:

      • Replace AdvancedResourceHandler with ExtendedResourceHandler, which is a more descriptive name,
      • Use the same pattern from myfaces shared, because it is well tested.
      • Use a SAXParser to load files, since the proposed solution is java 1.6 specific, and compatibility with jdk 1.5 is required.

      I'll commit the proposal, but keep the previous code so we can discuss over there.

      There are no Sub-Tasks for this issue.

        Activity

        Hide
        Leonardo Uribe added a comment -

        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.

        Next objective is work on the parser and the possible options that could be configured from that location.

        Show
        Leonardo Uribe added a comment - 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. Next objective is work on the parser and the possible options that could be configured from that location.
        Hide
        Leonardo Uribe added a comment -

        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.

        Show
        Leonardo Uribe added a comment - 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.
        Hide
        Mark Struberg added a comment -

        We shall drop GZIP handler since this is not a plugable solution.

        IF any projects needs a zip handler, then this will get applied via a reusable ServletFilter and not via hardcoding this functionality into each and every of our applications.

        Show
        Mark Struberg added a comment - We shall drop GZIP handler since this is not a plugable solution. IF any projects needs a zip handler, then this will get applied via a reusable ServletFilter and not via hardcoding this functionality into each and every of our applications.
        Hide
        Mark Struberg added a comment -

        Just to clarify that before any questions come up: zipping in any JSF resource handler is really only needed because JSF-2 allows EL expressions in resources, making them non-cachable! This is what we like to get rid of with all the resource-loader proposal! Thus we also can just rely on good old techniques like having an Apache httpd with mod-file-proxy which does all the static file caching, accept-header parsing and zipping if the client supports it.

        Show
        Mark Struberg added a comment - Just to clarify that before any questions come up: zipping in any JSF resource handler is really only needed because JSF-2 allows EL expressions in resources, making them non-cachable! This is what we like to get rid of with all the resource-loader proposal! Thus we also can just rely on good old techniques like having an Apache httpd with mod-file-proxy which does all the static file caching, accept-header parsing and zipping if the client supports it.
        Hide
        Leonardo Uribe added a comment -

        Really EL expressions are only allowed on CSS files (use "#

        {resource['....']}

        "), and it should be "application scope", or in other words return the same value each time they are evaluated, making them cacheable.

        Show
        Leonardo Uribe added a comment - Really EL expressions are only allowed on CSS files (use "# {resource['....']} "), and it should be "application scope", or in other words return the same value each time they are evaluated, making them cacheable.
        Hide
        Mark Struberg added a comment - - edited

        this contradicts the JSF spec which explicitely notes the language and other el params which are obviously session scoped (or even per view). I cannot find ANY hint that this must be application scoped. Au contraire: currently JSF resources explicitely disables the cache if there is any el in them.

        Show
        Mark Struberg added a comment - - edited this contradicts the JSF spec which explicitely notes the language and other el params which are obviously session scoped (or even per view). I cannot find ANY hint that this must be application scoped. Au contraire: currently JSF resources explicitely disables the cache if there is any el in them.

          People

          • Assignee:
            Mark Struberg
            Reporter:
            Leonardo Uribe
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:

              Development