I am trying to write a JSF custom component that dynamically chooses creates and renders an existing composite component. So far everthing is working fine except for passing attributes to the composite.
This is my custom component class (error handling etc. stripped for better reading):
@FacesComponent(createTag = true)
public class ChooseEZComp extends UIComponentBase {
@Override
public void encodeBegin(FacesContext context) throws IOException {
Object value = getAttributes().get("value");
String ezCompName = value.getClass().getSimpleName().toLowerCase();
// ezCompName is something like "freelink" or "treenode"
Map<String, Object> params = new HashMap<>();
params.put("node", value);
// log.debug(params.get("node").getClass().getName()) -> yields correct class name
ViewDeclarationLanguage viewDeclarationLanguage = context
.getApplication()
.getViewHandler()
.getViewDeclarationLanguage(context, context.getViewRoot().getViewId());
UIComponent component = viewDeclarationLanguage
.createComponent(context,
"http://xmlns.jcp.org/jsf/composite/ezcomp",
ezCompName,
params);
component.encodeAll(context);
}
}
A composite component (I have several of them), that gets choosen and rendered by this class:
<cc:interface>
<cc:attribute name="node" required="true"/>
</cc:interface>
<cc:implementation>
<h:outputText value="The class of node is: #{cc.attrs.node.class.name}"/>
</cc:implementation>
This is how I use the tag in my JSF page:
<test:chooseEZComp value="#{treeView.selectedNode.data}"/>
So "value" is always guaranteed not of type java.lang.String (it's some JPA @Entity).
But nevertheless the result output in the JSF page is always:
The class of node is: java.lang.String
Where am I wrong? Isn't it possible to pass something other than String as parameter to an composite?
I am runnind wildfly-8.2.0-final with Java EE 7 (and Primefaces 5 but which is not used here)
Any hints welcome!
Edit: of course I also tried to force the type of the attribute in the cc:interface
<cc:interface>
<cc:attribute name="node" required="true" type="some.package.type"/>
</cc:interface>
But this consequently resulted in a IllegalArgument Exception:
IllegalArgumentException: Cannot convert ... of type class java.lang.String to class