A good idea. This is not supported by the JSF API, but it is theoretically possible using a special script renderer. I played around a bit, and it's really possible. Just create a MultiScriptRenderer that extends ScriptRenderer and override encodeEnd() to check if the name attribute contains the * template, and then process it accordingly by scanning the files matching that template in the resource folder.
Here is an example run:
package com.example; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.Map; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import com.sun.faces.renderkit.html_basic.ScriptRenderer; public class MultiScriptRenderer extends ScriptRenderer { @Override public void encodeEnd(FacesContext context, UIComponent component) throws IOException { Map<String, Object> attributes = component.getAttributes(); String name = (String) attributes.get("name"); if (name.contains("*")) { String pattern = name.replace(".", "\\.").replace("*", ".*"); String library = (String) attributes.get("library"); File root = new File(context.getExternalContext().getRealPath("/resources/" + (library != null ? library : ""))); for (File file : root.listFiles()) { if (file.getName().matches(pattern)) { attributes.put("name", file.getName()); super.encodeEnd(context, component); } } attributes.put("name", name);
Register it in faces-config.xml as follows (Sorry, @FacesRenderer annotation will not work until it is fixed in JSF 2.2 for this specific corner case, see also JSF issue 1748 ):
<render-kit> <renderer> <component-family>javax.faces.Output</component-family> <renderer-type>javax.faces.resource.Script</renderer-type> <renderer-class>com.example.MultiScriptRenderer</renderer-class> </renderer> </render-kit>
Works great on Mojarra 2.0.3. You can use templates such as *.js and prefix*.js . A specific code example is only associated with a specific JSF implementation for storing a code template. It also requires the WAR to expand upon deployment, otherwise browsing the directory using File#listFiles() will be impossible (which thus excludes some (older) versions / configurations of servlet containers). For other JSF implementations, you will need to expand its ScriptRenderer or write a completely new one if you want to be implementation independent (which should be pretty simple, just look at the standard ScriptRenderer source if you are stucks).
source share