Can I access the expression string of a ValueExpression passed as attribute value to my taglib component?
My goal is to programmatically derive missing attribute values from it. In this case I'm trying to avoid having to repeat an attribute as a literal.
now:
<a:columnText title="name" value="#{entity.name}" sortBy="entity.name" />
desired:
<a:columnText title="name" value="#{entity.name}" />
-taglib.xml
<tag>
<tag-name>columnText</tag-name>
<source>column-text.xhtml</source>
<attribute>
<name>value</name>
<required>true</required>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
</attribute>
<attribute>
<name>sortBy</name>
<required>false</required>
</attribute>
</tag>
column-text.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:a="http://www.kwa.nl/jsf/app-legacy" xmlns:c="http://java.sun.com/jstl/core">
<c:if test="#{empty sortBy}">
<a:expressionAsLiteral var="#{sortBy}" value="#{value}" />
</c:if>
<p:column headerText="#{title}" sortable="true" sortBy="#{sortBy}">
<h:outputText value="#{value}"/>
<a:sortByUnwrapper/>
</p:column>
</ui:composition>
<a:expressionAsLiteral />
is intended to unwrap the ValueExpression '#{value}' to '#{entity.name}' and set '#{sortBy}' to the literal 'entity.name'. In this example to feed the primefaces sortBy column.
public class ExpressionAsLiteral extends TagHandler {
private final TagAttribute var;
private final TagAttribute value;
public ExpressionAsLiteral(TagConfig config) {
super(config);
var = getRequiredAttribute("var");
value = getRequiredAttribute("value");
}
@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
// abstracted for example.
setAsLiteral(ctx, var, unwrapFaceletAttributeValue(ctx,value));
}
}
My debugger tells me the information needed is hidden in value's ValueExpressionImpl private VariableMapper varMapper
. My problem is unwrapping the returned ValueExpressionImpl without resorting to code smells.
My google-fu is failing me. I get the feeling my approach is all wrong, any tips?
EDIT #1:
Attempted the following. Results in #{value}
instead of desired attribute value #{iRow.title}
.
valueExpressionString = value.getValueExpression(ctx, Object.class).getExpressionString();