class RequiredInterceptor {

    @AroundInvoke
    public Object checkRequiredParameters(InvocationContext ctx) throws Exception {
        // Check to see if any of the parameters are required
        Object[] methodParams = ctx.getParameters();
        if (null != methodParams && methodParams.length > 0) {
            Annotation[][] annotations = ctx.getMethod().getParameterAnnotations();
            if (null != annotations && annotations.length > 0) {
                for (int i = 0; i < annotations.length; i++) {
                    Object methodParameter = methodParams[i];
                    Annotation[] methodAnnotations = annotations[i];
                    if (null != methodAnnotations && methodAnnotations.length > 0) {
                        // Check to see if the Required annotation exists
                        boolean required = false;
                        String paramName = null;
                        String[] validValues = null;
                        for (Annotation a : methodAnnotations) {
                            if (a.annotationType().equals(Required.class)) {
                                Required r = (Required) a;
                                paramName = r.value();
                                validValues = r.validValues();
                                required = true;
                                break;
                            }
                        }
                        log.debug("Checking parameter: " + paramName + ", value: " + methodParameter);
                        // If required and the methodParameter is null then fail
                        boolean fail = false;
                        if (required) {
                            if (null == methodParameter)
                                fail = true;
                            else if (methodParameter instanceof String && StringUtils.isEmpty((String) methodParameter))
                                fail = true;
                            else if (!isValidValuesEmpty(validValues) && !ArrayUtils.contains(validValues, methodParameter))
                                fail = true;
                        }
                        if (fail) {
                            StringBuilder errMsg = new StringBuilder();
                            errMsg.append("Parameter: '").append(paramName).append("' is required when calling '").append(ctx.getMethod()).append("'.");
                            if (null != validValues)
                                errMsg.append(" Valid values: ").append(ArrayUtils.toString(validValues));
                            String error = errMsg.toString();
                            log.error(error);
                            throw new IllegalArgumentException(error);
                        }
                    }
                }
            }
        }
        return ctx.proceed();
    }

}