-
1. Re: Dependecny Injection in JSF Validator
kragoth Dec 2, 2009 5:51 AM (in response to charliebarjel)Please post your entire validator bean code as there's probably a few different ways this problem could happen.
-
2. Re: Dependecny Injection in JSF Validator
charliebarjel Dec 2, 2009 6:10 AM (in response to charliebarjel)Here is my entire validator code:
package au.com.statewater.koncentrator.action; import java.io.Serializable; import java.math.BigDecimal; import java.util.Iterator; import javax.el.ValueExpression; import javax.faces.application.FacesMessage; import javax.faces.component.NamingContainer; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; import org.jboss.seam.Component; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.intercept.BypassInterceptors; import org.jboss.seam.log.Log; import au.com.statewater.koncentrator.action.home.SiteVariableRelationHome; import au.com.statewater.koncentrator.entity.SiteVariableRelation; import au.com.statewater.koncentrator.entity.SiteVariableRelationId; @Name("readingValidator") @Scope(ScopeType.CONVERSATION) @org.jboss.seam.annotations.faces.Validator @BypassInterceptors public class ReadingValidator implements Validator, Serializable { /** * Auto-generated Id */ private static final long serialVersionUID = 1169110644691617222L; @Logger Log log; //@In(value = "siteVariableRelationHome", create = true, required = true) //private SiteVariableRelationHome siteVariableQueryHome; private final String ATTRIBUTE_Panel = "attrPanel"; private final String ATTRIBUTE_FormTable = "attrFormTable"; private final String ATTRIBUTE_SiteId = "attrSiteId"; private final String ATTRIBUTE_VaribleId = "attrVariableId"; @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { String readingValue = (String) value; String siteId = getSelectedSiteId(context, component); String variableId = getSelectedVariableId(context, component); SiteVariableRelationId id = new SiteVariableRelationId(siteId, variableId); SiteVariableRelationHome siteVariableQueryHome = (SiteVariableRelationHome) Component.getInstance("siteVariableRelationHome"); siteVariableQueryHome.setSiteVariableRelationId(id); SiteVariableRelation svRelation = siteVariableQueryHome.getInstance(); BigDecimal minValue = svRelation.getMinValue(); BigDecimal maxValue = svRelation.getMaxValue(); if (!newReadingValid(readingValue, minValue, maxValue)) { throw new ValidatorException(new FacesMessage("Reading is not between allowed values (Min: " + minValue + " - Max: " + maxValue + ")")); } } private boolean newReadingValid(String readingValue, BigDecimal minValue, BigDecimal maxValue) { Integer reading; try { reading = Integer.parseInt(readingValue); if ((reading.intValue() >= minValue.intValue()) && reading.intValue() <= maxValue.intValue()) { return true; } } catch (NumberFormatException nfe) { // Cannot parse reading - Not integer return false; } catch (NullPointerException npe) { // Variable has no MIN and MAX values return true; } return false; } private String getSelectedSiteId(FacesContext context, UIComponent component) { String attributeSiteId = (String) component.getAttributes().get(ATTRIBUTE_SiteId); UIComponent readingsTable = getFormTable(context, component); UIInput siteId = (UIInput) readingsTable.findComponent(attributeSiteId); return (String) siteId.getValue(); } private String getSelectedVariableId(FacesContext context, UIComponent component) { String attributeVariableId = (String) component.getAttributes().get(ATTRIBUTE_VaribleId); UIComponent readingsTable = getFormTable(context, component); UIInput variableId = (UIInput) readingsTable.findComponent(attributeVariableId); return (String) variableId.getValue(); } /** * Find and return the JSF Form Table component that contains the form field values * @param context invoked context * @param component component containing attribute values * @return form table component */ private UIComponent getFormTable(FacesContext context, UIComponent component) { String attributePanel = (String) component.getAttributes().get(ATTRIBUTE_Panel); String attributeFormtable = (String) component.getAttributes().get(ATTRIBUTE_FormTable); // Find JSF root component UIComponent readingsPanel = context.getViewRoot().findComponent(attributePanel); // Find JSF Form Table component that contains form fields return readingsPanel.findComponent(attributeFormtable); } }
Thanks for your help.
Charlie
-
3. Re: Dependecny Injection in JSF Validator
kragoth Dec 2, 2009 7:42 AM (in response to charliebarjel)Alrighty, your problem is all because of one line of code you have.
@BypassInterceptors
I would really recommend reading the doco surrounding this annotation, but I'll try explain simply.
The @BypassInterceptors annotation does exactly what it sounds like. It means the Seam interceptors will bypass this bean. The Seam interceptors will not fire on this bean. Now, Bijection is done BY an interceptor. So, if you put this annotation on your class Bijection will never occur becuase you have told Seam to not intercept it.
Now, on a validator I believe it is actually recommended to have the @BypassInterceptors annoatation present so... you are basically limited to using Component.getInstance(Bean.class) or any variants of Component.getInstance() to get an instance of a Seam bean.
On a side note, are Validators normally Conversation scoped? Seems a little odd to me, but I could be wrong.
I hope this helps a little. I'll try keep an eye on the thread incase you have more questions.
-
4. Re: Dependecny Injection in JSF Validator
charliebarjel Dec 2, 2009 12:26 PM (in response to charliebarjel)Thanks for your help Tim.
It make sense to me now.
And you're right, I need the @BypassInterceptors on the validator.So I might have to stick to Component.getInstance().
Just a quick question though on something you mentioned...what is the best scope for my validator to sit in?
Thanks again
Charlie
-
5. Re: Dependecny Injection in JSF Validator
kragoth Dec 3, 2009 12:29 AM (in response to charliebarjel)Hey Charlie,
I was always under the impression that Validators are Event scoped.
Looking into the Seam examples I came across this Validator.
@Name("wikiCaptchaValidator") @Validator(id = "wikiCaptchaValidator") public class WikiCaptchaValidator implements javax.faces.validator.Validator, Serializable {
Notice the lack of the @Scope annotation. From my understanding this means that it would be Event scoped.
That being said, I can't think of any reason why Conversation scope will give you a problem, I just don't think it's considered necessary.
Anyways, I'm glad you've got a good understanding of what's going on now.
Cheers,
Tim -
6. Re: Dependecny Injection in JSF Validator
charliebarjel Dec 3, 2009 2:26 AM (in response to charliebarjel)Thanks again for your help Tim.
Appreciate it.