You can use UIViewRoot#addComponentResource()
to programmatically add JSF resources. You can use a SystemEventListener
on PostAddToViewEvent
of <h:head>
for this.
public class DynamicHeadResourceListener implements SystemEventListener {
@Override
public boolean isListenerForSource(Object source) {
return "javax.faces.Head".equals(((UIComponent) source).getRendererType());
}
@Override
public void processEvent(SystemEvent event) {
String library = "yourLibraryName";
String name = "yourScript.js"; // Can be dynamic here.
addHeadResource(FacesContext.getCurrentInstance(), library, name);
}
private void addHeadResource(FacesContext context, String library, String name) {
UIComponent resource = new UIOutput();
resource.getAttributes().put("library", library);
resource.getAttributes().put("name", name);
resource.setRendererType(context.getApplication().getResourceHandler().getRendererTypeForResourceName(name));
context.getViewRoot().addComponentResource(context, resource, "head");
}
}
In order to get it to run, register it in faces-config.xml
of your module project as below:
<system-event-listener>
<system-event-listener-class>com.example.DynamicHeadResourceListener</system-event-listener-class>
<system-event-class>javax.faces.event.PostAddToViewEvent</system-event-class>
<source-class>javax.faces.component.UIOutput</source-class>
</system-event-listener>