DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > Tapestry IOC aware JSR-303 Custom Validators

Tapestry IOC aware JSR-303 Custom Validators

Taha Siddiqi user avatar by
Taha Siddiqi
·
May. 28, 11 · Java Zone · Interview
Like (0)
Save
Tweet
4.73K Views

Join the DZone community and get the full member experience.

Join For Free

In JSR-303, adding a custom field validator is a two step process.

  1. Create an annotation which will be placed on a field to be validated
  2. Create a validator which implements ConstraintValidator and link it to the above annotation


But there are situations where in you may need to access Tapestry services inside the validator. By default the validators are instantiated by ConstraintValidatorFactory which is by default provided by the ValidatorFactory. So to allow tapestry-ioc to resolve dependencies within the validators, we need to take instantiation into our own hands. Let us create a simple validator which will invoke a service to check if the name of an object is correct. (Stupid but simple)

Create an annotation

We start with an annotation

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Constraint(validatedBy = FooNameConstraintValidator.class)
public @interface FooNameConstraint {

public abstract String message() default "{com.googlecode.tawus.exports.FooNameConstraint.message}";

public abstract Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}

All the three attributes are required and specify the message to be displayed, groups() to which this annotation is added to and payload() to assign custom payload objects(not used by API itself). Notice that we have linked the validator class using @Constraint attribute.

Create a validator

The validator is very simple.

public class FooNameConstraintValidator implements
ConstraintValidator<FooNameConstraint, String> {

private FooNameCheckService fooNameCheckService;

public FooNameConstraintValidator(FooNameCheckService fooNameCheckService){
this.fooNameCheckService = fooNameCheckService;
}

public void initialize(FooNameConstraint constraintAnnotation) {
}

public boolean isValid(String value, ConstraintValidatorContext context) {
return fooNameCheckService.isValid(value);
}

}

This validator calls FooNameCheckService to validate the name. As the validators are created only once, we can use only those services which have default scope. Per-thread services can be accessed by injecting ObjectLocator and the calling getService() method with the required Service interface as argument. FooNameCheckService is defined as

//Interface
public interface FooNameCheckService {
boolean isValid(String Name);
}

//Implementation
public class FooNameCheckServiceImpl implements FooNameCheckService {

public boolean isValid(String name) {
//Check if the length is more than 5
return name != null && name.length() > 5;
}

}

Create Tapestry IOC Aware ConstraintValidatorFactory

Now, we have to take control of the instantiation of the validator. This can be done by providing our own implementation of ConstraintValidatorFactory.

public class TapestryConstraintValidatorFactory implements ConstraintValidatorFactory {

private ObjectLocator locator;

public TapestryConstraintValidatorFactory(ObjectLocator locator){
this.locator = locator;
}

public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
return locator.autobuild(key);
}

}

Contribute ConstraintValidatorFactory

Finally, we contribute this to BeanValidatorSource in the module class

@Contribute(BeanValidatorSource.class)
public static void provideBeanValidatorConfigurer(
final ObjectLocator locator,
OrderedConfiguration<BeanValidatorConfigurer> configuration) {
configuration.add("constraint-validator", new BeanValidatorConfigurer() {
public void configure(javax.validation.Configuration<?> configuration) {
configuration.constraintValidatorFactory(new TapestryConstraintValidatorFactory(locator));
}
});
}

We also need to contribute this to hibernate-core, otherwise it will try to use its own implementation of ConstraintValidatorFactory. This can done by turning off the default validation by setting javax.persistence.validation.mode to none in hibernate.cfg.xml

<property name='javax.persistence.validation.mode'>none</property>

and then contributing an event-listener to the hibernate configuration

 

public static void contributeHibernateSessionSource(
final ObjectLocator locator,
OrderedConfiguration<HibernateConfigurer> config) {
config.add("hibernateConfiguration", new HibernateConfigurer() {
public void configure(org.hibernate.cfg.Configuration configuration) {
Configuration<?> validationConfig = Validation.byDefaultProvider()
.configure();
validationConfig
.constraintValidatorFactory(new TapestryConstraintValidatorFactory(locator));
BeanValidationEventListener listener = new BeanValidationEventListener(
validationConfig.buildValidatorFactory(), configuration
.getProperties());
listener.initialize(configuration);
configuration.setListener("pre-insert", listener);
configuration.setListener("pre-delete", listener);
configuration.setListener("pre-update", listener);
}

});
}

 

From http://tawus.wordpress.com/2011/05/12/tapestry-magic-12-tapestry-ioc-aware-jsr-303-custom-validators/

Annotation Attribute (computing) Implementation Dependency Payload (computing) API Links Hibernate Interface (computing)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Is DataOps the Future of the Modern Data Stack?
  • 5 Ways to Optimize Your CQL Queries for Performance
  • What Is Edge Compute? It’s Kind of Like Knitting Dog Hats
  • Demystifying Cloud-Native Data Management: Layers of Operation

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo