Two JSF libraries providing the same renderer - jsf

Short Version:
If two JSF library jar files both include a custom renderer for the same family and type, is there any way from within the library itself (i.e. not from the containing app) of specifying which one should be used? Something like assigning a priority, with higher ones used in preference to lower ones?
Longer Version:
I'm using Primefaces in a project and trying to override the provided head renderer with my own:
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.Head</renderer-type>
<renderer-class>com.example.MyHeadRenderer</renderer-class>
</renderer>
</render-kit>
If I put that into the WEB-INF/faces-config.xml of the war file then it's all good, and my renderer gets used.
However, if I try to deploy my code as part of a library jar (my-utils.jar), with the renderer defined in META-INF/faces-config.xml, then the Primefaces one is used. This contains exactly the same definition, so I'm guessing it just depends on the order they get loaded. Indeed, renaming my library to "xx-comps.jar" works, so it would appear that JSF is loading faces-config.xml files from all jar files in alphabetical order, with later entries just overwriting earlier ones.
Is there any way of forcing the selection to my library?
So far, I have these options:
Put my renderer directly into the WEB-INF/faces-config.xml of the war.
Build a custom Primefaces jar with that one renderer definition
removed.
Rename my library and rely on some (undocumented as far as I can
see) behaviour from the JSF loader.
Add a custom renderkit which extends the standard one, and reference
that from my war WEB-INF/faces-config.xml.
The first three all work but are not ideal, as (1) and (2) require changes outside my library, and (3) just looks dodgy as hell....
The fourth is just an idea as I've never written a render kit before so not aware of the effort involved. No idea if it is practical or would work, but it is better than (1) because at least the application only references a single render kit, and does not need to be updated if/when new renderers are added. Happy to put more effort into researching this approach if it seems a reasonable solution.
Also, I'd ideally prefer to use annotations rather than XML:
#FacesRenderer(componentFamily = "javax.faces.Output", rendererType = "javax.faces.Head")
public class MyHeadRenderer extends Renderer {
...
}
Thanks

You can specify the ordering via <ordering> in faces-config.xml of the JAR.
E.g. if you want your utility library to be loaded after all others, then just do so:
<ordering>
<after>
<others />
</after>
</ordering>
If you want to force an explicit ordering, then hook on specifically PrimeFaces, which has a <name>primefaces</name> in its faces-config.xml:
<ordering>
<after>
<name>primefaces</name>
</after>
</ordering>

Related

How exactly does p:panelGrid extends h:panelGrid

I'm using Primefaces and I know that p:panelGrid extends h:panelGrid as it's clearly stated in the documentation.
However I can't see the exact difference between them. What extra functionalities does p:panelGrid provide? In which cases should I prefer using the Primefaces version over the HTML Basic one?
Although p:panelGrid extends h:panelGrid, it actually lacks many of the attributes that h:panelGrid contains. Which ultimately got me confused.
I can't speak for PrimeFaces' actual intention (I'm no PrimeFaces developer), but based on my observations so far, I can only conclude that they omitted attributes which only invite bad practices in HTML perspective (mainly HTML-deprecated attributes — use CSS instead) or makes no sense otherwise (and are better at its place in a parent or child component). I can only say that it's a Good Thing.
Upon further inspection in the source code I can also confirm that it doesn't technically extend from <h:panelGrid> (HtmlPanelGrid class), but from the UIPanel superclass (which is also used by a.o. <h:panelGroup>). This design decision is most likely done to have more flexibility in the rendered output as shown in the showcase.
Generally, you should only prefer an enhanced component whenever you start to actually need the enhanced/new feature. This usually only happens once you figure out you actually need such one feature and discover that it is missing in the standard component. You'd then usually already know the keywords you're looking for and simply start exploring the component libraries using those keywords if they haven't already implemented it.

Omnifaces: Using CombinedResourceHandler with Richfaces

when using CombinedResourceHandler in a Richfaces application only stylesheets and user defiend scripts are combined. The standard JavaScript resource and all Richfaces specific resources remain as seperated resources.
The Omnifaces documentation states:
RichFaces has the same problem with several JS files, but this is so far not exactly trivial to workaround
So my question is what this 'non-trivial workaround' would be?
As far as I can see, CombinedResourceHandler wont handle resources when getRendererType() returns org.richfaces.renderkit.ResourceLibraryRenderer. These are then handled by org.richfaces.renderkit.html.ResourceLibraryRenderer.
I am not sure what would be the best way to combine RichFaces behaviour with OmniFaces here.
I was able to create a solution by modifying OmniFaces CombinedResourceHandler.
Details in short:
Richfaces utilizes a concept called ResourceLibrarys wich means a resource may not only be a single file but instead a collection of those files. For example, RichFaces uses a resource named base-component.reslib. RichFaces ResourceHandler interpretes this resource dependency as dependency to
javax.faces:jsf.js
jquery.js
richfaces.js
richfaces-base-component.js
So the CombinedResourceHandler needed some extra functionality to seperate dependencies to ordinary Resources from Richfaces ResourceLibraries. The latter needed to be resolved according to specifications obtained from RichFaces sources.
It was not trivial to work this around without modifying the CombinedResourceHandler itself. The CombinedResourceHandler itself has really to be modified to use a reflection hack which extracts the resources from RichFaces' org.richfaces.resource.ResourceLibraryFactoryImpl. The reflection hack is necessary in order to keep OmniFaces free of RichFaces dependencies so that it can be used together with other component libraries like PrimeFaces.
As per issue 107, this was implemented in 1.3-20121206.

developing library controls for xpages

I' working on a library control for Xpages and need some help in creating.
I would create a control which reads a configuration file and creates controls in a table, controls like Editboxes, checkboxgroups and so on.
so and now to my questions:
could I initiate controls from the Exlib or must I implement them all by my self?
if I could use them from the Exlib could anyone explain me how?
I hope its clear what i mean if not please ask me for further informations.
When creating your own components, if you're closely replicating some behavior that is already in an extension library component, I highly recommend you extend that component and just add what's needed to accommodate your different functionality. This makes things much easier and you don't have to code around every little scenario that the component might be placed in.
But, if you are developing a component that is nothing like any of the extension library or core components then just ensure your component extends UIComponent or UIComponentBase. If going this route, you'll also need to create your own renderer which extends Renderer. This is what will build the on-screen representation of your component. Again, if there's already something in the core components or extension library components that closely mimics what you need then make your renderer extend that renderer. Also, don't forget to include the renderer definition in the faces-config file and the component definition in the xsp-config file or your component won't work.
As for initiating controls from the extlib.... I assume you mean can you inject them onto the page at runtime. If so the answer is absolutely yes. To add an input text field to the page where there is a container (i.e. panel, div, span, whatever) with an ID of "someContainer"
XspInputText input = new XspInputText();
input.setValue("someValue");
input.setId("someID");
UIComponent container = FacesContext.getCurrentInstance().getViewRoot().findComponent("someContainer");
container.getChildren().add(input);
To see the api for all of the core and extension library components take a look at the XPages Controls Documentation. For a more complete tutorial on creating your own components take a look at my blog for creating a custom component inside an nsf, the steps are pretty much the same for putting them into a library:
Part 1,
Part 2 and there is an example database in the Part 2 post.

Managed beans in xsp-config files

Can anyone tell me if it is possible to keep managed beans in separate .xsp-config configuration files?
And if yes than how to do this? I have tried and it only worked if I put them into faces-config.xml file.
If you want to split your bean definitions into multiple configuration files, you'll need to create an OSGi plugin. XSP libraries can contain more than one faces-config file (and you can name them whatever you want, because you specify in the library class which XML files contain faces-config definitions). But in an NSF, you're limited to just the auto-generated faces-config.xml file.
Yes, Managed beans must be defined in the faces-config.xml file.
For a good reference on all the different options within faces-config and xsp-config take a look at this website. It describes the format of pretty much everything you might ever want to add to a faces-config or xsp-config and a brief description of the options.
As far as I know they have to be in the faces-config.xml
faces-config is a JSF implementation, you should check out the JSF specification for this, there are even some good post in this forum like this one:
JSF faces config file outside WEB-INF?

How many ways there are to declare variables in facelets?

I noticed that c:set does not work well used inside "include of include of include", as important notice facelets documentation does't recommend it too.
Now I am using ui:param inside ui:include, but it is a bit dispersive when no attached notes about params comes with the include, is there something other way to declare "global vars"?
This is really a matter of trying to fit old JSP programming into the JSF framework. You should be using backing beans to hold your data.
If you try to hard-code data directly into your xhtml file, you are defeating the purpose of JSF's MVC framework. If you have a specific example of what you are trying to do, I could give you a specific recommendation.

Resources