package org.qi4j.library.validation;
import org.qi4j.api.common.AppliesTo;
import org.qi4j.api.common.AppliesToFilter;
import org.qi4j.api.concern.ConcernOf;
import org.qi4j.api.injection.scope.This;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* After invocation, ensure that the validation rules pass.
* <p/>
* This applies to all methods which throws ValidationException
*/
@AppliesTo( ChangeValidationConcern.AppliesTo.class )
public class ChangeValidationConcern extends ConcernOf<InvocationHandler>
implements InvocationHandler
{
public static class AppliesTo
implements AppliesToFilter
{
private final Method checkValidMethod;
public AppliesTo()
{
try
{
checkValidMethod = Validatable.class.getMethod( "checkValid" );
}
catch( NoSuchMethodException e )
{
throw new Error( "Invalid interface", e );
}
}
public boolean appliesTo( Method method, Class mixin, Class compositeType, Class modelClass )
{
if( method.equals( checkValidMethod ) )
{
return false;
}
Class[] exceptionClasses = method.getExceptionTypes();
for( Class exceptionClass : exceptionClasses )
{
if( ValidationException.class.isAssignableFrom( exceptionClass ) )
{
return true;
}
}
return false;
}
}
@This Validatable validatable;
public Object invoke( Object object, Method method, Object[] objects ) throws Throwable
{
try
{
return next.invoke( object, method, objects );
}
finally
{
// Ensure that object is still in a valid state
validatable.checkValid();
}
}
}