Ryan has posted 7 posts at DZone. View Full User Profile

JSF 2.0 New Feature Preview Series (Part 2.1): Resources

09.02.2008
| 7223 views |
  • submit to reddit

This is the second blog in the JSF 2.0 New Feature Preview Series. The previous entry covered ProjectStage, now we'll cover Resources. Keep in mind that none of the features described are final, and may change, but this is a good opportunity to show the features as they exist now and illicit feedback.

The term Resources is pretty vague, so let's clarify that first.  Resources are any artifacts that a component may need in order to be rendered properly to a user-agent.  So think images, CSS, or JavaScript files.

Previous versions of JSF had no facility for serving resources, so component libraries either had to cook up their own mechanism for serving resources or use something like Weblets so that these resources could be packaged with their component library.

JSF 2.0 will have support for this functionality out of the box which should make life easier for custom component developers.

Packaging 

The default implementation will look for resources in two locations and in the following order:

  1. /resources  this location represents resources in the webapp itself
    and if present, must be in the root of the web application
  2. /META-INF/resources this location represents resources on the
    classpath

First question that may come to mind is why care about resources in the docroot of the web application?  Don't worry, that will be touched on soon.

The spec further supplies some options for how to structure content under these resources directories.  This specification looks like this:

  • [localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]
    items in [] are optional

Let's break these elements down starting with localePrefix.  This allows the developer to associate a resource with a particular locale identifiter.  If a developer wishes to leverage this feature, they must add a key/value pair like:

  • javax.faces.resource.localePrefix=<localePrefix>

The value of localePrefix must match the localePrefix within the resources directory.

Next in the path is libraryName.  This is a logical identifier that may be used to represent a grouping of resources.  This library may be versioned as indicated by libraryVersion. Finally we we have resourceName.  This is the name of the physical resource (i.e. mast.jpg or corp.css or js/ajax.js), which can also be versioned.

Let's take a closer look at versioning.  Version strings are pretty open ended.  They may be 1.1, 1.1.1, 1.1.2.11, etc., and if used, the resource handling mechansim must use the lastest version available (be it library or resource).  This allows you to update resources at runtime without having to redeploy the application.

The ability to update resources at runtime touches back on looking for resources within the docroot of the web application.  Consider the following scenario.  An application uses a component library with resources included within the JAR, for argument's sake, let's say that the resource path is /META-INF/resources/compLib/script/compScript.js.  A bug is found in this .js file and no new version of the component library is available. The bug can be fixed locally and placed in /resources/compLib/1.1/script/compScript.js while the app is live and the new version will be sent to the client.

The last item I wanted to mention with respect to resource (not library) versioning as, at first blush, it's a bit strange.  The name of the resource is actually the directory, and the version is the resource content itself.

The next blog entry will get into the details of the API, but I want to mention it here as I feel it's important.  From an API persective, the versioning and localePrefix features are transparent in the API.  This means when leveraging the API, the only info that is needed is a library name (if any), and the resource name.  The resource system takes care of the localePrefix and version resolution automatically.

References
Published at DZone with permission of its author, Ryan Lubke. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)