JSF Validation with Parameters

Goal

Create a JSF validator that gets context information as an attribute

Description

Recently, I had the need to create a validation method (actually, this recipe can also be used when creating a validation class!) that would perform its validation logic based on some information that should be passed as an argument, somehow. The problem is that the validation method has to be defined with a specific interface, something similar to the following:

public void validateMethod(FacesContext context, UIComponent toValidate, Object value) 
                           throws ValidatorException {
...
}

How to

Due do the fact that the validate method gets as argument the component that should be validated, the idea is to simply associate context information as an attribute to that component and get its value inside the validation method. So, putting this idea into practice, lets assume we have a list of days (the days of a week) and that, for each day, we may report hours to any project associated to a given user but for each day, one project cannot be selected more than once. To implement this, we need to define a validator to a selectOneMenu component and state to that validator which entry we are dealing with in the list of entries:

<h:selectOneMenu value="#{timesheetEntry.projectAssignment}"
  styleClass="span12"
  converter="#{timetrack.projectAssignmentBean.converter}"
  validator="#{consultantBean.validateAssignmentChange}">
  <f:attribute name="currentEntry" value="#{timesheetEntry}" />
  <f:selectItems
    value="#{consultantBean.getActiveProjectAssignments(timesheetEntry.projectAssignment)}"
    var="projectAssignment"
    itemLabel="#{projectAssignment.project.projectCode}"
    itemValue="#{projectAssignment}" />
    <p:ajax event="change" process="@this" />
</h:selectOneMenu>

The important part in the previous snippet is the specification of the attribute “currentEntry” and the definition of the validation method. With the previous definition, it is now only a matter of implementing the appropriate logic on the validator (only the relevant part is shown at this point…):

public void validateAssignmentChange(final FacesContext context, final UIComponent toValidate, 
    final Object value) throws ValidatorException {
  final TimesheetEntryWrapper changingEntry = (TimesheetEntryWrapper) toValidate.
                                              getAttributes().get("currentEntry");
  ... business logic specific implementation and instantiation of facesmessages
}

Explanations

Whenever a validator needs information that is not directly accessed through the bean in which it is implemented, when it is a validator method or, when it is a validation class which does not have any reference to the bean to which it has been associated, we may use the validating component’s attributes to specify more context information and implement the logic we need for our specific case.

Advertisements

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s