4

I have a JSF Validator that I'm building that has properties in it that I would like to have loaded from a ResourceBundle. However, I'm not quite sure how to work this, as it isn't loading properly. Any ideas on how I can make this work?

I've tried using a @PostContruct to do it, but I'm getting the following error in Eclipse:

Access restriction: The type PostConstruct is not accessible due to restriction on required library /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar

So, I'm not too sure what the best way to work this. A sample of what I'm talking about is below...

The validator...

@FacesValidator("usernameValidator")
public class UserNameValidator implements Validator {

  @ManagedProperty(value="#{props_userNamePattern}")
  private String userNamePattern;  

  @ManagedProperty(value="#{props_minUserNameLength}")
  private int minUserNameLength;  

  @ManagedProperty(value="#{props_maxUserNameLength}")
  private int maxUserNameLength;

  public void validate(FacesContext context, UIComponent component, Object
        value) throws ValidatorException {
    //My validations here...   
  }

  //Setters for the class properties

}

faces-config.xml

<resource-bundle>
    <base-name>settings</base-name>
</resource-bundle>

settings.properties

props_userNamePattern = /^[a-z0-9_-]+$/
props_minUserNameLength = 3
props_maxUserNameLength = 30
mikesir87
  • 1,785
  • 1
  • 20
  • 25

3 Answers3

6

The @ManagedProperty works on @ManagedBean classes only. The @PostConstruct will also not be the correct solution for your functional requirement. It is intented to be placed on a method which is to be executed when the class has been constructed and all dependency injections are been finished. The error which you're facing is caused by a specific combination of older Eclipse+JRE versions. If upgrading is not an option, you could disable the warning/error by Window > Preferences > Java > Compiler > Errors/Warnings > Deprecated and restricted API > Forbidden reference > Ignore.

As to your functional requirement, unfortunately no annotation which achieves that comes to mind. You could however get it programmatically.

String bundlename = "settings";
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
ResourceBundle bundle = ResourceBundle.getBundle(bundlename, locale);
String usernamePattern = bundle.getString("props_userNamePattern");
// ...

You can do that in the constructor of the validator. When used properly a new instance will be created for every view anyway.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

Adding to the correct answer of BalusC; In JSF 2.0/2.1 Validators, Converters, PhaseListeners, etc are a kind of 'second-class' citizen as they are not injection targets.

This also means you can't inject an entity manager or an EJB, which can sometimes be used for validation purposes.

In JSF 2.2 this is supposed to change:

All JSF lifecycle artifacts should be CDI-aware and support injection/JSR-299/JSR-330 (PhaseListeners, NavHandlers, Components, ActionListeners, everything.)

See: http://jcp.org/en/jsr/detail?id=344

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140