Skip to content

Instantly share code, notes, and snippets.

@Yyukan
Created December 16, 2015 08:04
Show Gist options
  • Save Yyukan/c5e907bc5bad6a1f96bf to your computer and use it in GitHub Desktop.
Save Yyukan/c5e907bc5bad6a1f96bf to your computer and use it in GitHub Desktop.
/**
* Wires {@link Validate} annotation with rest call to perform validation on the request entity
* ...
* @POST
* ...
* @Validate(RequestValidator.class)
* public Response restCall(TransportModel request)
*
* <aop:aspectj-autoproxy />
*/
@Aspect
@Component
public class ValidatorAspect {
@Autowired
private ApplicationContext context;
@Around(value = "@annotation(annotation)", argNames = "restCall,annotation")
public Object validate(ProceedingJoinPoint restCall, Validate annotation) throws Throwable {
// lookup for validator based on the provided by annotation
final GenericValidator validator = context.getBean(annotation.value());
final Object[] arguments = restCall.getArgs();
if (arguments.length != 1) {
throw new IllegalArgumentException("Expected only one argument on the method marked with @Validate " +
"annotation with value [" + annotation.value() + "]");
}
// transport model validation
final Option<Failure> result = validator.validate(arguments[0]);
// if valid proceed with the rest call otherwise proceed with validator
return (result.isEmpty()) ? restCall.proceed() : validator.proceed(result.get());
}
}
/**
* Annotates REST resource methods to provide validation for transport models
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate
{
/**
* Provides validator class
*/
Class<? extends GenericValidator> value();
}
/**
* Defines common operations for transport model validators
*/
@Component
public abstract class GenericValidator<T extends GeneratedMessage, R extends GeneratedMessage> implements Validator<T> {
@Autowired
private HttpServerAccessor httpServerAccessor;
@Autowired
private FailureProvider failure;
public abstract R transform(Failure failure);
protected Option<Failure> reject(int errorCode, String errorMessage) {
return Option.option(failure.create(errorCode, errorMessage));
}
protected Option<Failure> accept() {
return Option.none();
}
protected Response proceed(Failure failure) {
return httpServerAccessor.newPostResponse(transform(failure)).build();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment