Abel Dofino

Greenhorn
+ Follow
since Sep 03, 2008
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Abel Dofino

Hi.

Because of lack of examples a lot of people got into the same issue: they add attribute to UIComponent with some EL expression but in the Validator they couldn't get the value by callng component.getAttributes().get("attributeName"). Last one always returned null. But for some reason if the add attribute with plain text value it worked fine.

Today I decided to digg into it and after re-reading specification for JSF 1.2 I got the answer: there are 2 places for attribute values! Here is the quote of the description for section "9.4.2 <f:attribute> (page 9-17)":

"If the associated component already has a component attribute with that name, take no action.
Otherwise, call the isLiteralText() method on the argument value. If it returns
true, store the value in the component�s attribute Map under the name derived above.
If it returns false, store the ValueExpression in the component�s ValueExpression
Map under the name derived above."

In other words we looked for value in wrong place. If value of f:attribute is EL expression we should use component.getValueExpression("attributeName") to get ValueExpression instance and call getValue(elContext) to get theValue.

Here is 2 examples.

Example 1. Value of attribute is plain text.

Page code:

<h:inputText id="userName" value="#{mybean.userName}">
<f:attribute name="payCode" value="regular"/>
<f:validator id="userNameValidator"/>
</h:inputText>
...
faces-context.xml

<validator>
<validator-id>userNameValidator</validator-id>
<validator-class>your.package.UserNameValidator</validator-class>
</validator>
...
Validator code

public class UserNameValidator implements Validator {

public void validate(FacesContext context, UIComponent component, Object value) {
String paycode = component.getAttributes().get("payCode");
...

}

Example 2. Value of attribute is EL (expression language).

Page code:

<h:inputText id="userName" value="#{mybean.userName}">
<f:attribute name="payCode" value="#{otherBean.payCode}"/>
<f:validator id="userNameValidator"/>
</h:inputText>
...
faces-context.xml

<validator>
<validator-id>userNameValidator</validator-id>
<validator-class>your.package.UserNameValidator</validator-class>
</validator>
...
<managed-bean>
<description>Some other bean we get value from. Scope "request" just for example. It could be session or application too or even no scope</description>
<managed-bean-name>otherBean</managed-bean-name>
<managed-bean-class>your.package.OtherBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>

OtherBean code:

public class OtherBean {

private PayCode payCode;
...

public PayCode getPayCode() {
return this.payCode;
}

public void setPayCode(PayCode payCode) {
this.payCode = payCode;
}
}


...
Validator code

public class UserNameValidator implements Validator {

public void validate(FacesContext context, UIComponent component, Object value) {
ValueExpression ve = component.getValueExpression().get("payCode");
PayCode paycode = (ve != null) ? (PayCode)ve.getValue(context.getELContext()) : null;

...

}



I beleive that you could extend my examples for JSF Converters, ValueChangeListeners and ActionListeners. Now you know where look for attribute value!
[ September 03, 2008: Message edited by: Viacheslav Garmash ]
12 years ago
JSF