Yes, it's possible. You can achieve this by using a specific resource library name and have a custom ResourceHandler intercept on it and return a custom Resource when a resource of the specific library is been requested.
E.g.
<h:outputScript library="dynamicJs" name="some.js" />
with
public class DynamicJsResourceHandler extends ResourceHandlerWrapper {
public DynamicJsResourceHandler(ResourceHandler wrapped) {
super(wrapped);
}
@Override
public Resource createResource(String resourceName, String libraryName) {
if ("dynamicJs".equals(libraryName)) {
return new DynamicJsResource(resourceName);
} else {
return super.createResource(resourceName, libraryName);
}
}
}
and
public class DynamicJsResource extends Resource {
private String resourceName;
public DynamicJsResource(String resourceName) {
this.resourceName;
}
@Override
public String getRequestPath() {
// TODO: return "/context/javax.faces.resource/" + resourceName + ".xhtml?ln=dynamicJs";
}
@Override
public URL getURL() {
// TODO: return new URL("http://localhost:8080" + getRequestPath());
}
@Override
public Map<String, String> getResponseHeaders() {
// TODO: return desired HTTP response headers.
}
@Override
public InputStream getInputStream() throws IOException {
// TODO: return InputStream by resourceName.
}
@Override
public boolean userAgentNeedsUpdate(FacesContext context) {
// TODO: return true when resource has been modified in server side.
}
}
To get it to run, register it as follows in faces-config.xml:
<application>
<resource-handler>com.example.DynamicJsResourceHandler</resource-handler>
</application>
If you happen to use JSF utility library OmniFaces, then you can also save the boilerplate code and extend from its org.omnifaces.resourcehandler.DynamicResource instead so you only need to implement getInputStream(). If you don't use OmniFaces, then you can always use its source code as guidance.