class TimerSettingsValueValidator implements ConstraintValidator<ValidTimerSettingsValue, TimerSettingsValue> {

    @Override
    public boolean isValid(TimerSettingsValue timerSettings,
                           ConstraintValidatorContext constraintValidatorContext) {
        String value;
        String errorMessage = null;

        if (timerSettings.getTimeDuration() != null) {
            value = timerSettings.getTimeDuration();
            if ((looksLikeExpression(value) && !isValidExpression(value)) ||
                    (!looksLikeExpression(value) && !isValidDuration(value))) {
                errorMessage = TimeDurationInvalid;
            }
        } else if (ISO.equals(timerSettings.getTimeCycleLanguage())) {
            value = timerSettings.getTimeCycle();
            if ((looksLikeExpression(value) && !isValidExpression(value)) ||
                    (!looksLikeExpression(value) && !isValidRepeatableInterval(value) &&
                            !isValidRepeatableDateTimeInterval(value) && !isValidRepeatableStartEndInterval(value) &&
                            !isValidRepeatablePeriodEndInterval(value))) {
                errorMessage = ISOTimeCycleInvalid;
            }
        } else if (CRON.equals(timerSettings.getTimeCycleLanguage())) {
            value = timerSettings.getTimeCycle();
            if ((looksLikeExpression(value) && !isValidExpression(value)) ||
                    (!looksLikeExpression(value) && !isValidCronExpression(value))) {
                errorMessage = CronTimeCycleInvalid;
            }
        } else if (timerSettings.getTimeDate() != null) {
            value = timerSettings.getTimeDate();
            if ((looksLikeExpression(value) && !isValidExpression(value)) ||
                    (!looksLikeExpression(value) && !isValidTimeDate(value))) {
                errorMessage = TimeDateInvalid;
            }
        } else {
            errorMessage = NoValueHasBeenProvided;
        }

        if (errorMessage != null) {
            constraintValidatorContext.disableDefaultConstraintViolation();
            constraintValidatorContext.buildConstraintViolationWithTemplate(errorMessage)
                    .addConstraintViolation();
            return false;
        }
        return true;
    }

}