views:

368

answers:

2

Hi,

I'm trying to implement a custom validation annotation in Seam.

We have a list of objects, lets call it arrayA, and arrayA is different dependent on today's date.

Next we have an input field stringB, stringB is some value in arrayA going through a transformation function funcC(...).

So basically, we can validate stringB using the following loop:

for(a : arrayA)
{
    a.equals( funcC( stringB ) )
    return true
}
return false

My problem is, how do I do this in seam considering arrayA is dynamic? The seam/hibernate validation annotation seems to take only constants as input. Does anyone know a workaround for this problem?

Thanks!

A: 

Hi Jonh,

First of all, Java Server Faces, the view technology used by Seam, is a Server side based component technology. If you have a dynamic Array property, so i hope you are updating the JSF Tree (you can use Ajax4JSF - default in RichFaces or ICEFaces).

As shown in your question, you have a complex validation (It involves more than on property and are dependent on processing of business logic). So the best place to put is inside your business logic. Think about it.

regards,

Arthur Ronald F D Garcia
+2  A: 

You can always utilize Seam's Component.getInstance() from within your Validator to fetch the Array from your context. This assumes that you have populated a Seam-based Bean containing this array.

For example:

@Name("someValidator")
@Validator
public class SomeValidator implements javax.faces.validator.Validator {

  public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {

    MyArrayBean bean = (MyArrayBean)Component.getInstance("myArrayBean");
    String[] arrayA = bean.getArray();

    for(String a : arrayA) {
      //etc
    }
  }
}

Alternately, if the Array can change depending on the page you are validating from; then you can always pass the value to the validator using <f:attribute>.

For example:

<h:inputText value="#{someBean.stringB}">
    <f:validator validatorId="someValidator" />
    <f:attribute name="arrayA" value="#{myArrayBean.array}"/>
</h:inputText>

And in your validator, in place of the Component.getInstance() you can load this array via the attribute:

String[] arrayA = component.getValueExpression("arrayA").getValue(context.getELContext());

[Note if passing the String[] doesn't work then pass in the Bean containing it instead.]

Damo