Introduction

Some myfaces components needs to reference javascript, css and images for some components. To leverage the usability of these components myfaces introduces the AddResource component which can be used to add references to external resources to a rendered html page. These resources where loaded by the browser through separate requests. Currently AddResource can be used for the following tasks:

add inline javascript and css to page head definition (same content is rendered only one time)

add external javascript and css files to page head definition (same reference is rendered only one time)

add external javascript and css files to current location (same reference may be rendered multiple times)

handles external references to images, javascript and css files who are located in myfaces jar files.

Interface ResourceHandler

A ResourceHandler instance controls how a ResourceLoader class identifies which resource must be loaded. This is normally done by applying paramters to the url through param=value or by defining a custom uri. AddResource will prefix this uri with data to identify that the request is an AddResource request and to know which ResourceLoader class is responsible for serving the response for the request.

public interface ResourceHandler
{
/**
* Returns the resource loader class which is used to load the resource
*
* @return a class which implements org.apache.myfaces.component.html.util.ResourceLoader
* @see ResourceLoader
*/
Class getResourceLoaderClass();
/**
* Returns the uri part which is used by the resourceloader to identify the resource to load.
*
* @param context
* @return the returned resource uri will be passed as the resourceUri parameter for
* the ResourceLoader.serveResource method (omitting request parameters)
* @see ResourceLoader#serveResource(HttpServletRequest, HttpServletResponse, String)
*/
String getResourceUri(FacesContext context);

Interface ResourceLoader

A ResourceLoader is responsible to render the content to the response. How the content is loaded or created depends on the implementation of the ResourceLoader instance. Since AddResource needs to create an instance of the ResourceLoader it is nessessary that a default constructor is defined for the implementation.

That's how tomahawk components use it. Unless the uri your want to load resources from starts with org/apache/myfaces/custom, it won't work for your custom component. The reason is that, by default, myfaces uses the MyFacesResourceHandler, which itself uses MyFacesResourceLoader. It's that ResourceLoader that, by security, limit access to that signel part of classpath. This is a security feature, it prevents specially crafted urls to be used to retrieve your configurations files, etc. Keep this in mind when using the solution suggested below, you will have to implement your own security rules to protect your configuration files.

Suppose you classes and resources are in com.company.jsf. You will need 3 things to be able to use them in custom components:

create a custom ResourceLoader, that will serve your ressources and do some security checks