jTransfo 0.10 is now available. It contains several improvements and a few bug fixes. For the full list of issues solved see the issue tracker.
The most important change introduced in this release is the introduction of convert interceptors. The convert interceptors are called around each jTransfo convert call. They allow you to do validations and cause side-effects on the conversions.
For example a converter could be used to automatically add “last modified” information in domain objects.
For example, assuming objects which can contain last update metadata extend AbstractChangeLoggedObject and that there is a spring service which fills the metadata, you can use the code below. When using the jtransfo-spring module, the interceptors are automatically added (you can order them using the @Order() annotation if needed).
@Component public class MetadataUpdateConvertInterceptor implements ConvertInterceptor { @Autowired private MetaDataUpdater metaDataUpdater; @Override public <T> T convert(Object source, T target, boolean isTargetTo, ConvertSourceTarget next, String... tags) { T res = next.convert(source, target, isTargetTo, tags); if (res instanceof AbstractChangeLoggedObject) { metaDataUpdater.update((AbstractChangeLoggedObject) res); } return res; } } |
You can also use this mechanism to integrate bean validations. Using spring this could be done by including the following service:
@Component public class BeanValidationConvertInterceptor implements ConvertInterceptor { @Autowired private SpringValidatorAdapter validator; @Override public <T> T convert(Object source, T target, boolean isTargetTo, ConvertSourceTarget next, String... tags) { T res = next.convert(source, target, isTargetTo, tags); if (!isTargetTo) { // only validate on the domain objects, not on transfer objects BindingResult bindingResult = new MapBindingResult(new HashMap(), ""); validator.validate(res, bindingResult); if (bindingResult.hasErrors()) { Set<ConstraintViolation<?>> violations = new HashSet<ConstraintViolation<?>>(); for (ObjectError error : bindingResult.getAllErrors()) { violations.add(new ConstraintViolationImpl(error.getDefaultMessage(), error.getDefaultMessage(), res.getClass(), res, res, res, PathImpl.createPathFromString(error.getObjectName()), null, null)); } throw new MyConstraintViolationException(violations); } } return res; } private static class MyConstraintViolationException extends ConstraintViolationException { private MyConstraintViolationException(Set<ConstraintViolation<?>> constraintViolations) { super(constraintViolations); } @Override public String getMessage() { return toString(); } @Override public String toString() { return "ConstraintViolationException " + this.getConstraintViolations(); } } } |
Recent Comments